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 fail2banIf 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 = wordpressfailregex = ^<HOST>.*].*POST.*/wp-login\.php HTTP.*ignoreregex =
# DEV Notes:## Rule Author: Ilija MatoskiWhat 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 = wordpressfailregex = ^<HOST>.*].*/xmlrpc\.php.*ignoreregex =
# DEV Notes:## Rule Author: Ilija MatoskiNow 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 = truefilter = wordpress-xmlrpcaction = iptables-multiport[name=WordPressXMLRPC, port="http,https"]logpath = /var/log/apache2/access_logmaxretry = 10
[wordpress-login]
enabled = truefilter = wordpress-loginaction = iptables-multiport[name=WordPressLogin, port="http,https"]logpath = /var/log/apache2/access_logmaxretry = 10If you are running Plesk, then replace the logpath with
logpath = /var/www/vhosts/system/*/logs/*access*log /var/log/apache2/*access.logSo 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-WordPressLoginChain fail2ban-WordPressLogin (1 references)target prot opt source destinationREJECT all -- 189.1.169.141 anywhere reject-with icmp-port-unreachableREJECT all -- 181.140.198.180 anywhere reject-with icmp-port-unreachableREJECT all -- 117.21.191.227 anywhere reject-with icmp-port-unreachableRETURN all -- anywhere anywhere
$ iptables -L fail2ban-WordPressXMLRPCChain fail2ban-WordPressXMLRPC (1 references)target prot opt source destinationREJECT all -- 117.21.191.227 anywhere reject-with icmp-port-unreachableRETURN all -- anywhere anywhere