On Christmas some bored Latvian (according to whois
) ‘script kid’ decided to try-and-break into one of my WordPress installations with brute force login attempts. Not a problem as such, because I had already taken precautions against such attempts, but his idiotic fooling around caused the account to become locked, preventing me from logging in!!! I had to take the server offline for about an hour or so, before I could log in myself.
I didn’t want to allow that to happen again, especially because that stupid kid continued his attacks. I started searching for ways to block the login attempts by-IP-address, and found out that it was possible to configure the (already installed) program fail2ban
to protect WP logins, too. Here’s a howto about doing it the Gentoo Linux way:
The prerequisites: already working WP installation, fail2ban
and rsyslog
. Or in Gentoo speak:
emerge -av fail2ban rsyslog
rc-update add fail2ban default
rc-update add rsyslog default
If you have some other system logger already installed, please stop and remove it before starting rsyslog
. In case you want to continue using that other syslogger, you have to figure out the exact syntax for its configuration file for yourself. I suppose because you are already running WP, you have a ‘mysql’ use-flag in your make.conf. If not, add it before typing in the above.
First, you need to add the following to the top (just after the <?php tag) of the functions.php file within the WP theme you are using.
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']}" );
}
This constructs a syslog facility called LOCAL1. I have three WordPress installations on virtual hosts on my server, so I repeated the above on all three, substituting LOCAL1 with LOCAL2 and LOCAL3. The code above hooks into the WP login failed action, and tells it to log the failed login attempt with the IP address, username used and website it is coming from.
Next, edit /etc/rsyslog.conf
# Save WP invalid login attempts to log for Fail2Ban
local1.* /var/log/wp_f2b.log
local2.* /var/log/wp_f2b.log
local3.* /var/log/wp_f2b.log
This creates the rule and the file to accept the log attempts.
(UPDATE Feb 19th,2015: with rsyslog-8.x.x and up, it is not advisable to edit the rsyslog.conf file itself; instead, create a file with a name 10-wp.conf
in /etc/rsyslog.d/
, and copy the code above into it.)
Restart rsyslog
rc-service rsyslog restart
At this point you should be able to test it to verify the attempts (if any) are being logged:
tail -f /var/log/wp_f2b.log
Next step is to create the filter for fail2ban
; first edit/create /etc/fail2ban/jail.local
[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
ignoreip = 127.0.0.0/8 your_ip_here
maxretry = 5
findtime = 600
bantime = 600
Substitute your email address to the default ones above. You can also alter the maxretry, findtime and bantime (in seconds) values. Be sure to whitelist your own IP-address in the ignoreip section, otherwise you might ban yourself by accident.
If you have the BulletProof Security or a similar security plugin installed, I suggest that you set the maxretry value at least one smaller than the security plugin’s corresponding value, so fail2ban
can ban the intruder before the account becomes locked-up.
Then create /etc/fail2ban/filter.d/wordpress.conf
# Fail2Ban configuration file
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = wordpress
failregex = ^%(__prefix_line)sWordpress authentication failure for .* from <host>$
ignoreregex =
</host>
You could now test things with:
fail2ban-regex /var/log/wp_f2b.log /etc/fail2ban/filter.d/wordpress.conf
Last, you should create a file /etc/logrotate.d/wordpress
in case the log file grows too large
/var/log/wp_f2b.log {
size 30k
create 0600 root root
rotate 5
}
That’s it! Fail2ban
should now automatically ban the IP-addresses where the failed login attempts come from. And while you are at it, you should also configure fail2ban
to protect ssh
, ftp
or other possible services you have on your server.
Original source: TSCADFX