If you run a wordpress blog, you really should be aware that there is a global attack on wordpress blogs going on.
It’s coming from a bot net and is an attempt to find blogs that have their admin account enabled with easy to guess passwords.
I noticed the attack a couple of months ago when, while watching my web server log scrolling by, I noticed a significant number of attempts to use the wp-login.php script from random IP addresses.
A bit of research turned up information on the global attack.
Obviously I wanted to do something about it to protect my server.
The most obvious approach is to disable, or rename, the admin account on your blog. At the very minimum you should change the password on the admin account to something very strong. Personally, I like GRC’s “Perfect” password generator for this kind of thing.
There are three other approaches that I’ve heard of that can work also…
- Rename the wp-login.php script in your wordpress directory. This means that nobody can log in unless they know what you’ve renamed the script to. The downside of this approach is that, when you upgrade, the script is replaced. Also, this does nothing to reduce the network traffic on the web server.
- Install a wordpress security plug-in. One that was recommended to me is WordFence. This plug-in apparently has very robust security mechanisms… but it is run as a service and requires registration. The basic level of service is free, but to get higher service levels costs money. This also does nothing to reduce the network traffic on your web server.
- Block attacking IP addresses using a firewall. This requires three pieces of software: fail2ban, a reactive security monitor, iptables, the linux firewall, and the wordpress plug-in WP fail2ban.
I went with option 3. It has a number of advantages …
- Blocking the IP at the firewall stops the attacking host from getting to any blogs hosted on the system.
- Blocking the IP reduces the network traffic on the web server.
- The fail2ban security package can monitor more than just the wordpress blog (in fact it wasn’t intended for this purpose, but works quite nicely). fail2ban was originally designed to protect systems from brute force password attacks on SSH servers.
- fail2ban also can send a notification email to the administrator of the IP address (using the ARIN whois database).
So the first thing to do is setup fail2ban.
I had already been running fail2ban to protect my SSH & SMTP servers, so this wasn’t an issue. Setting it up isn’t hard and, if you are running your own server, you should probably run something like this to prevent brute force attacks.
fail2ban protects the system by monitoring log files for entries indicating that a bad password was entered. It would look for entries like
Jun 1 00:53:00 gondor1 sshd: Failed password for invalid user admin from 18.104.22.168 port 59314 ssh2
If it detects more than 5 entries like that in a short period of time (60 seconds), it uses iptables to block the IP that the attempt came from.
The wp-fail2ban plug-in leverages that functionality by sending a message to syslog (the standard linux logging mechanism) indicating that the blog, user profile, and IP address.
Jun 1 16:55:23 gondor1 wordpress(planet-i.org): Authentication failure for admin from 22.214.171.124
fail2ban can monitor that log file for the entry (it uses regular expressions to do pattern matching) and, when it discovers more than 5 entries from a single IP, it blocks the IP.
The filter config file for fail2ban is included in the wp-fail2ban plug-in.
I tweaked the filter pattern a bit … it now specifically targets attempts to log in with an administrator account…
failregex = ^%(__prefix_line)sAuthentication failure for admin(istrator)? from <HOST>$
All you have to do is add an entry to the fail2ban config file (jail.conf) to activate the filter and specify the actions to perform.
Here is the entry I use.
[wp-iptables] enabled = true filter = wordpress action = iptables[name=wp, port=http, protocol=tcp] sendmail-whois[name=wordpress, email@example.com, firstname.lastname@example.org] logpath = /var/log/messages maxretry = 1
By setting the maxretry to 1, any attempt to log in with the admin (or administrator) account will get the IP blocked.
The actions I use adds an entry to the firewall using iptables, then it sends ME a message indicating that it detected the attack, and finally it tries to send an email to the owner of the IP address indicating that they might have a problem.
The email notification is somewhat enlightening … last night I had 150 notifications that fail2ban had taken action.
I’ve only gotten a few responses from the owners of the IP addresses that the attacks are coming from.