3 minute read

Brute Force Attack Prevention for WordPress Using Fail2Ban

Giving Your Web Server a Break

There are several WordPress plugins out there that make it simple to protect your website from brute force attacks. They do their job very well, but if your site’s traffic is on the high end these plugins can create an additional load on your server which may not be acceptable to you. This is because WordPress has to handle all login requests, and that means both PHP and the database are used. Even if an attacker’s IP address is blacklisted by the plugin, WordPress will still load and make a database query every time that IP address tries to login. This is okay if traffic is low, but if it’s high or if you’re under a brute force attack, all those PHP requests and database queries will help take your server down. Ideally, we want to handle brute force protection on the server before the traffic hits WordPress at all.

Web Server Messages Log
Brute Force Attempts in a Web Server Log

A great solution to this is Fail2Ban, a very popular intrusion detection software package that is very easy to install and configure. It silently scans server log files for bad login attempts and when an IP address makes too many attempts, Fail2Ban will add a rule to the server’s firewall dropping all future traffic from that IP for a certain amount of time. Since this happens at the OS level, WordPress is not involved and therefore neither is PHP or the database.

Installing Fail2Ban

You can see if Fail2Ban is already installed on your server by running this command: fail2ban-server -V. If you need to install it, there are many good tutorials out there. I won’t cover it here since I don’t know what flavor of Linux your server is running. However, I will be using CentOS examples later in this article since it’s the most common on web servers.

Installing WP Fail2Ban Plugin

Wait! Didn’t I say that we don’t want to use a plugin? Don’t worry, this plugin does not handle the actual brute force security. It simply logs failed WordPress login attempts to the system log. Fail2Ban does all the heavy lifting of scanning this log and enforcing IP blocks.

First, download the plugin and extract the files. Drop the wp-fail2ban.php file into your wp-content/mu-plugins directory. You may need to create this directory if it doesn’t exist. By installing the plugin this way, it cannot be deactivated in the WordPress backend.

Install Custom Fail2Ban Filter

Drop the wordpress.conf file into Fail2Ban’s filter directory at /etc/fail2ban/filter.d/. This filter contains the regex that Fail2Ban uses to find the failed WordPress logins in the system log.

Configure Custom Fail2Ban Jail

Create a new file called wordpress.conf in /etc/fail2ban/jail.d/. Paste the following into your jail file.

enabled = true
filter = wordpress
logpath = /var/log/messages
port = http,https
maxretry = 5
findtime = 3600
bantime = 86400
action = iptables-multiport[name=Wordpress, port="http,https"]

Basically, this file is telling Fail2Ban what log to scan, what constitutes grounds for blocking, and what method to use to block the IP. In this case, we’re scanning the /var/log/messages log, allowing up to 5 failed login attempts within 3600 seconds (1 hour), blacklisting offenders for 86400 seconds (24 hours), and using iptables to block offenders. iptables is your server’s firewall software.

Feel free to adjust these values to suit your own preferences. You may need to change the value for logpath depending on your system.

Restart Fail2Ban

Before Fail2Ban can start using this new setup, you need to restart the service.

service fail2ban restart

If everything is setup correctly, Fail2Ban should restart without any errors.

Testing Things

With all of this in place, Fail2Ban is now actively monitoring and blocking brute force logins to WordPress. You can test this out by performing a bad login to your website and then viewing your system log. You’ll see an entry like this:

May 19 18:11:16 server wordpress(example.com)[16504]: Authentication failure for administrator from 123.456.789.0

When someone gets blacklisted, you will see this type of entry in the log:

May 19 18:20:22 server fail2ban.actions[31444]: WARNING [wordpress] Ban 123.456.789.0

You will also see an entry in iptables dropping all traffic from this IP:

1 DROP all -- 123.456.789.0

As a result of this iptables rule, any futher reqeusts from this IP address will be dropped. We’ve successfully blocked the attacker before they hit WordPress. After 24 hours (or whatever time frame you’ve set), Fail2Ban will remove this rule from iptables and the IP address will be allowed access again.

This setup will definitely be a big help in controlling server load on high-traffic websites. Let me know of any other Fail2Ban/WordPress tips you may be aware of in the comments!

Adam Walter is a front-end developer, lover of WordPress, and Director of Development at Vital in Portsmouth, NH. Read more about me →