Configure fail2ban to Ban nginx 403 Forbidden Requests

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

Installation overview

  • 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: 189.167.27.53, 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: 189.167.27.53, 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) [2] ^ \[error\] \d+#\d+: .* forbidden .*, client: <HOST>, .*$
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [2] 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.