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.
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 -- 220.127.116.11 anywhere reject-with icmp-port-unreachable REJECT all -- 18.104.22.168 anywhere reject-with icmp-port-unreachable REJECT all -- 22.214.171.124 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 -- 126.96.36.199 anywhere reject-with icmp-port-unreachable RETURN all -- anywhere anywhere