fail2ban for Wordpress and Plesk
I’m hosting quite a bit of pages that run WordPress, and one of the biggest problem that I ran into is that people don’t keep their WordPress or plugin installations updated.
I gave up on having everyone upgrade, because they all use different plugins, customized plugins, and a lot of other stuff that will break if they upgrade.
So here comes fail2ban to the rescue, we can use it to go through the logs, to configure the system to ban the users when they fail to log in, or do some bad stuff, or try to brute force their way into the wordpress installation, either through the login form or through xmlrpc.
You should install fail2ban if you haven’t already, on debian based you would just issue.
apt-get install fail2ban
If you use Plesk you can skip creation of the files, and just use the frontend to create the necessary jails and filters, also replace common.conf with apache-common.conf.
The configuration is located in /etc/fail2ban on most systems.
So firstly let’s create a filter.
In /etc/fail2ban/filter.d, create a file called wordpress-login.conf, and put the following text inside.
# Fail2Ban filter for WordPress Login
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = wordpress
failregex = ^<HOST>.*].*POST.*/wp-login\.php HTTP.*
ignoreregex =
# DEV Notes:
#
# Rule Author: Ilija Matoski
What this does it creates a filter to be used in the next step. Also let’s create one filter for XMLRPC for WordPress in the same directory named wordpress-xmlrpc.conf
# Fail2Ban filter for WordPress XMLRPC
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = wordpress
failregex = ^<HOST>.*].*/xmlrpc\.php.*
ignoreregex =
# DEV Notes:
#
# Rule Author: Ilija Matoski
Now let’s create two new jails, that we gonna use to ban the people who are gonna abuse this.
In the folder /etc/fail2ban/jail.d, wordpress.conf,
[wordpress-xmlrpc]
enabled = true
filter = wordpress-xmlrpc
action = iptables-multiport[name=WordPressXMLRPC, port="http,https"]
logpath = /var/log/apache2/access_log
maxretry = 10
[wordpress-login]
enabled = true
filter = wordpress-login
action = iptables-multiport[name=WordPressLogin, port="http,https"]
logpath = /var/log/apache2/access_log
maxretry = 10
If you are running Plesk, then replace the logpath with
logpath = /var/www/vhosts/system/*/logs/*access*log
/var/log/apache2/*access.log
So in Plesk, the action will look like.
iptables-multiport[name="<NAME_OF_FILTER>", port="http,https"]
This will read the data from all the hosts in Plesk
So what happens if someone tries to POST to wp-login.php, or hit xmlrpc.php, 10 times in a 10 minute period he will be banned for a day, also there is a jail called recidive in fail2ban, which if you get jailed 5 times with the previous filters, the IP will get ban for a week.
You can adjust the times in the configuration file, if you want to lower or increase them.
Well this should work, now let it run for a while, and you can see what does your, after 15 minutes of running this is what was present in my logs.
$ iptables -L fail2ban-WordPressLogin
Chain fail2ban-WordPressLogin (1 references)
target prot opt source destination
REJECT all -- 189.1.169.141 anywhere reject-with icmp-port-unreachable
REJECT all -- 181.140.198.180 anywhere reject-with icmp-port-unreachable
REJECT all -- 117.21.191.227 anywhere reject-with icmp-port-unreachable
RETURN all -- anywhere anywhere
$ iptables -L fail2ban-WordPressXMLRPC
Chain fail2ban-WordPressXMLRPC (1 references)
target prot opt source destination
REJECT all -- 117.21.191.227 anywhere reject-with icmp-port-unreachable
RETURN all -- anywhere anywhere