Using Fail2Ban to block bruteforce Wordpress login attacks

Using Fail2Ban to block bruteforce Wordpress login attacks

A friend of mine hosts a lot of Wordpress sites and we regularly see a lot of brute force attempts from many different IP addresses repeatedly tring to login to the admin section of the site at wp-login.php

E.g.

mysite.com mysite.com 198.27.74.223 - - [26/Oct/2013:17:42:16 +0000] "POST /wp-login.php HTTP/1.0" 200 3747 "-" "-"
mysite.com mysite.com 208.84.146.60 - - [26/Oct/2013:17:42:16 +0000] "POST /wp-login.php HTTP/1.0" 200 3747 "-" "-"

This affects the load on the web server and we start to get load alerts from the ISP that provides the server.

To try and counter this I have setup the Fail2Ban tool on the server, which automatically blocks any IP that tries to login too many times repeatedly.

Configuring Fail2Ban

First install fail2ban, for CentOS it is available in the EPEL repository.

yum install fail2ban

Next, copy the jail.conf to jail.local for editing:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Now edit /etc/fail2ban/jail.local and add the following lines:

[apache-wp-login]

enabled = true
action   = iptables[name=wplogin, port=http, protocol=tcp]
           sendmail-whois[name=wplogin, dest=root, sender=fail2ban@example.com]
filter  = apache-wp-login
logpath = /var/log/httpd/access_log
maxretry = 5

This file tells fail2ban what to do when the filter apache-wp-login matches, it sets up an action using iptables that blocks port http (80) and sends an alert E-mail.

The maxretry line tells fail2ban to only allow 5 repeat login attempts before blocking. The default time window is 5 minutes, which is specified at the top of that file.

Next define a filter to match wp-login.php requests by creating the file /etc/fail2ban/filter.d/apache-wp-login.conf

[Definition]

# Option:  failregex
# Notes.:  Regexp to catch Apache dictionary attacks on Wordpress wp-login
# Values:  TEXT
#
failregex = [\w\.\-]+ [\w\.\-]+ .*] "POST /wp-login.php

The regex above matches a custom log format I use that shows both the requested HTTP host header and the match vhost server name fields.

Now start the service and ensure it starts on boot:

service fail2ban start
chkconfig fail2ban on

Now your server will block repeat requests for wp-login.php and E-mail you when a block occurs.