WordPress Login Security with Fail2Ban

label_outlinechat_bubble_outline Comment

WordPress login security is an important part of protecting your WordPress site against brute force login attempts. This is part 1 of 3 on how to protect your WordPress login. We’re going to start off by showing you how to protect the login with Fail2Ban. The reason we are starting off here is because this portion can be used on a non-modified login page meaning that it can be implemented on any WordPress install so long as you have root access to the server.

If you do not have root access or if you would like a solution that’s more user-friendly we highly recommend BulletProof Security Pro.

But wait, there’s a plugin for this!

There are quite a few plugins out there that also log and block login attempts. The only one that we would recommend using is our plugin (WireFlare WordPress Fail2Ban) which adds the below script to your functions.php file automatically. We actually highly suggest our plugin because it will remain active regardless of the theme. Plugins that log attempts for use with Fail2Ban log them in the auth.log, the downside to this approach is that Fail2Ban has to parse the entire auth.log in order to find those attempts. This creates excessive CPU usage and also makes it harder to export or view the log should you wish to use it on another server. Most other blocking plugins, aside from BPS Pro, attempt to process invalid logins which can lead to an increased chance of denial of service attacks.

Hey why not just check the access.log?

We could just check the access log, but have you seen that log during a brute force attack? It grows so large, so fast, that we would consume a LARGE amount of CPU attempting to process this log. Beware of posts that instruct you to scan this log.

For those that wish to continue with Fail2Ban lets get started:

First you need to access your themes funtions.php file or add our plugin (WireFlare WordPress Fail2Ban). If you add and activate our plugin please disregard this step. If you chose not to use the plugin edit this file and at the top, but within the php tags, place the following:

const SYSLOG_FACILITY = LOG_LOCAL1;
 
add_action('wp_login_failed', 'log_failed_attempt'); 
 
function log_failed_attempt( $username ) {
	openlog( 'wordpress('.$_SERVER['HTTP_HOST'].')', LOG_NDELAY|LOG_PID, SYSLOG_FACILITY);
	syslog( LOG_NOTICE, "Wordpress authentication failure for $username from {$_SERVER['REMOTE_ADDR']}" );
}

What we are doing here is constructing a syslog facility called local1. We are then hooking into the WP login failed action. We then tell it to log the failed login attempt with the ip address, username used and website that it’s coming from.

We will now edit the rsyslog.conf. Depending on your OS the location of this file will vary. For us the command is:

nano /etc/rsyslog.conf

In the rules section we will add the following at the bottom:

# Save WP invalid login attempts to log for Fail2Ban
local1.*                                                /var/log/wp_f2b.log

We have now created the rule and the file to accept the log attempts. We could have used the auth.log or messages log but parsing those logs requires more CPU. We want to make this as unobtrusive as possible.

In order to make sure the file exists run this command:

touch /var/log/wp_f2b.log

Restart rsyslog:

service rsyslog restart

You should be able to test at this point and run the following from shell to verify that the attempts are being logged:

tail -f /var/log/wp_f2b.log

Press CTRL-C to exit the tail when you are done.

Now we need to create the filter in fail2ban:

nano /etc/fail2ban/jail.local

Add the following:

[wordpress]

enabled  = true
filter   = wordpress
action   = iptables-multiport[name=WordPress, port="http,https"]
           sendmail-whois[name=WordPress, dest=email@domain.tld, sender=fail2ban@domain.tld]
logpath  = /var/log/wp_f2b.log
maxretry = 5
findtime = 600
bantime  = 600

You can change the ban time, find time and max retry to whatever you’d like.

We now need to create the filter by:

nano /etc/fail2ban/filter.d/wordpress.conf

and add the following:

# Fail2Ban configuration file
#
# Author: WireFlare
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = wordpress
failregex = ^%(__prefix_line)sWordpress authentication failure for .* from <HOST>$
ignoreregex =

You should have already tested that logging occurs. This will ensure that we have entries to parse. You should also ensure that you have your IP address whitelisted in the jail.local file otherwise you might ban yourself.

Restart fail2ban with:

service fail2ban restart

Lets test things with:

fail2ban-regex /var/log/wp_f2b.log /etc/fail2ban/filter.d/wordpress.conf

One last thing that we might want to consider is adding this file to log rotate in case it gets too large. Lets do this by:

nano /etc/logrotate.conf

Go to the bottom of the file and add:

/var/log/wp_f2b.log {
    size 30k
    create 0600 root root
    rotate 5
}

Check out Part 2 of WordPress Login Security here.
Check out Part 3 of WordPress Login Security here.

Get Fail2Ban Plugin for WordPress Developed by WireFlare.

If you’ve found this article helpful consider leaving a comment below!

From all of us at WireFlare we ask that you help others find the answers they are looking for. Please leave a comment or share this post!

About

Blog Bio Picture For Todd

I'm the President of WireFlare. I have a passion for creativity, online business and internet security. I strive to create a community that empowers people to be themselves. I'm an adventurist, fun loving and caring. Find me hiking in places most people don't dare to go!

Get a free consultation today!