Banning bots in nginx using fail2ban
Some days ago I started learning a bit more about fail2ban in order to ban bad HTTP petitions reaching my nginx server. Here is a brief of what I learnt and did.
fail2ban jails
Normally configured in /etc/fail2ban/jail.local
file. In this file you configure fail2ban jails. Each jail will search for a type of bad behavior and ban IPs with that specific pattern.
Here is an example of a little jail I made.
[nginx-block]
enabled = true
bantime = 600
findtime = 600
maxretry = 5
port = http, https
action = nginx-action
filter = nginx-block
logpath = /config/log/nginx/access.log
The parameters mean the following:
bantime
: How many seconds will the ban last for detected offenders.findtime
: Window of time for offense check.maxretry
: How many offenses will be tolerated.action
: What to do with banned users. In this case, this action is defined in thenginx-action
file.filter
: Definition of the offense. Just a regexp to find in the nginx logs. In this case, the filter is defined in thenginx-block
file.logpath
: Log file to check for offenses.
In other words, fail2ban will search periods of findtime
for matches in filter
. If more than maxretry
matches are found, the offender will be banned bantime
, executing action
action.
fail2ban filters
The /etc/fail2ban/filter.d/nginx-block.conf
filter defines a pattern to search, and could look like this:
[Definition]
failregex = ^<HOST> - - \[.\] "." (400|401|403|404|405|404) .*$
ignoreregex =
This filter matches with some HTTP errors in the log file.
<HOST>
corresponds to the IP address in the log. If you want to ban users with other types of behaviors, you just need to change the filter according to the offense you want to match.
fail2ban actions
The /etc/fail2ban/action.d/nginx-action.conf
action defines what to do with banned users. It can be whatever you want, from banning access to the server to sending a mail, executing a script…
In this example, the action
file looks like this:
[Definition]
actionstart = echo "" > /config/nginx/fail2ban-ip.conf && /usr/sbin/nginx -s reload
actionstop = echo "" > /config/nginx/fail2ban-ip.conf && /usr/sbin/nginx -s reload
actioncheck =
actionflush = echo "" > /config/nginx/fail2ban-ip.conf && /usr/sbin/nginx -s reload
actionban = echo -n "deny <ip>;" >> /config/nginx/fail2ban-ip.conf && /usr/sbin/nginx -s reload
actionunban = sed -i "s/deny <ip>;//g" /config/nginx/fail2ban-ip.conf && /usr/sbin/nginx -s reload
The names are quite auto descriptive. When a user is banned, an nginx deny clause is appended to the fail2ban-ip.conf
file.
Of course, this file is then included in the nginx conf, accurately banning the IPs contained in this file.
Other options for banning may be banaction = ufw
or banaction = iptables-allports
, which are firewall bans. Therefore, IPs banned with this methods will not even reach de nginx server.