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.
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 the
filter: Definition of the offense. Just a regexp to find in the nginx logs. In this case, the filter is defined in the
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
/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.
/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
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.