If you forbid certain paths or URLs with nginx to protect content you may want to use fail2ban to ban these 403 requests nginx captures. For example if you have renamed your login page using a plugin then typically the hacker bots will receive a 403 forbidden error when trying to log in. Similarly if you have fully disabled XMLRPC.php that CloudFlare have blogged about being a common attack vector.
This guide will show you how to use fail2ban to ban these bots at the server level using iptables automatically. Be careful to make sure you are not banning Google or other indexing sites!
Configure fail2ban to Ban nginx 403 Forbidden Requests
- Generate log data
- Configure fail2ban filter and jail
Generate Log data for 403 Errors
Go to the URL that is banned by your nginx virtual host to generate some log data
Show the last 50 lines of your nginx log file
tail -n 50 /var/log/nginx/logfile
I found these entries which will be used as the basis for the fail2ban filter for banning users who trigger 403 forbidden errors
2016/09/15 17:01:18 [error] 3176#3176: *1 access forbidden by rule, client: 220.127.116.11, server: guides.wp-bullet.com, request: "GET /wp-login.php HTTP/1.1", host: "guides.wp-bullet.com", referrer: "android-app://com.Slack" 2016/09/15 17:01:54 [error] 3176#3176: *1 access forbidden by rule, client: 18.104.22.168, server: guides.wp-bullet.com, request: "GET /wp-login.php HTTP/1.1", host: "guides.wp-bullet.com", referrer: "android-app://com.Slack"
Now that we have the log data we can create the fail2ban filter
Configure fail2ban for nginx 403 Forbidden Errors
We need to create the fail2ban filter which will match the errors from the log file. Then we create a jail to use that filter and ban users.
Create fail2ban Filter for nginx Forbidden Requests
Create then nginx filter
sudo nano /etc/fail2ban/filter.d/nginx-forbidden.conf
Add this regular expression which will match the 403 forbidden errors in the nginx logs
[Definition] failregex = ^ \[error\] \d+#\d+: .* forbidden .*, client: <HOST>, .*$ ignoreregex =
Ctrl+X, Y + Enter to Save and Exit.
Now we can test the nginx HTTP auth filter by scanning the error log specified in the nginx virtual host.
fail2ban-regex /var/log/nginx/wpbullet.error.log /etc/fail2ban/filter.d/nginx-forbidden.conf
You will see this output showing it found the login failures we generated before.
Running tests ============= Use failregex file : /etc/fail2ban/filter.d/nginx-forbidden.conf Use log file : log Results ======= Failregex: 2 total |- #) [# of hits] regular expression | 1)  ^ \[error\] \d+#\d+: .* forbidden .*, client: <HOST>, .*$ `- Ignoreregex: 0 total Date template hits: |- [# of hits] date format |  Year/Month/Day Hour:Minute:Second `- Lines: 2 lines, 0 ignored, 2 matched, 0 missed
Create fail2ban Jail for nginx Forbidden Requests
Make sure the you have a fail2ban jail folder
sudo mkdir -p /etc/fail2ban/jail.d
Create the fail2ban nginx http auth jail configuration file
sudo nano /etc/fail2ban/jail.d/nginx-forbidden.conf
Paste this configuration which uses the filter we created before, scans all nginx log files and bans users for 6000 minutes who fail 3 times in a 60 second period.
[nginx-forbidden] enabled = true filter = nginx-forbidden port = http,https logpath = /var/log/nginx/*error*.log findtime = 60 bantime = 6000 maxretry = 3
Now that we know have made the jail, test the fail2ban syntax so make sure it’s all working
sudo fail2ban-client -d
If you didn’t see any errors (warnings are OK) then we can restart fail2ban
sudo service fail2ban restart
Checking the nginx Forbidden fail2ban Status
The fail2ban client can be used to show the statistics of its jails
sudo fail2ban-client status nginx-forbidden
While testing on virtual machines I managed to get the gateway banned.
Status for the jail: nginx-forbidden |- filter | |- File list: /var/log/nginx/wp-bullet.error.log /var/log/nginx/error.log | |- Currently failed: 0 | `- Total failed: 3 `- action |- Currently banned: 1 | `- IP list: 192.168.60.1 `- Total banned: 1
You can also list the iptables
sudo iptables -L -n
This shows the iptables chain for the nginx-forbidden jail
Chain f2b-nginx-forbidden (2 references) target prot opt source destination REJECT all -- 192.168.0.1 0.0.0.0/0 reject-with icmp-port-unreachable RETURN all -- 0.0.0.0/0 0.0.0.0/0 RETURN all -- 0.0.0.0/0 0.0.0.0/0
Any bots that are scanning and triggering 403 forbidden errors on nginx will now be automatically banned by fail2ban.