WordPress botnet protection for websites on Apache 2

There’s a botnet out there that’s attacking WordPress sites, trying to brute-force guess their admin passwords. I recently got alerted there was a traffic spike on my website, which is unusual. I looked at the server access logs, and indeed, there was something trying to access my WordPress login page over and over. This is output from a tail /var/log/apache2/mysite-access.log:

46.105.113.8 - - [14/Apr/2013:22:57:20 -0400] "POST /blog//wp-login.php HTTP/1.1" 200 4115 "-" "Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.15) Gecko/20091028
15 Ubuntu/9.04 (jaunty) Firefox/3.0.15"
74.207.229.103 - - [14/Apr/2013:22:57:20 -0400] "POST /wp-cron.php?doing_wp_cron=1365994640.1665890216827392578125 HTTP/1.0" 200 222 "-" "WordPress/3.5.1; http://adamfeuer.com"

So what to do? I looked around for an article on how to protect myself from the botnet, but didn’t find any good ones. So that’s why I’m writing this article.

WordPress security plugins

If you only have one or a few WordPress sites to protect, as the article I link to above mentions, it looks like you can install a plugin to protect you. Both these will automatically block logins from IPs after a certain number of failed login attempts. I haven’t tried either yet.

Apache mod_security

I wanted a solution that would work for all the WordPress sites on my server. That meant something at the Apache configuration level, or in the OS. I’m running Ubuntu 12.04. Here’s what I did, and it seems to work – this solution will block all attempts to log into WordPress except from a whitelisted IP address.

  1. Install Apache mod_securitymod_security is an Apache module that helps prevent attacks like this, and does a lot of other cool security stuff.
  2. Make sure you follow the instructions in the article above to install the default rule set
  3. Find out your IP address of your home network – one way is to type “What is my IP address” into Google.
  4. Add the following rules into your /etc/modsecurity/modsecurity.conf file:
    # site configuration
    # allow all access from home
    SecRule REMOTE_ADDR "^1.2.3.4" phase:1,nolog,allow,ctl:ruleEngine=off
    # deny all access to wp-login or wp-cron - to prevent wordpress botnet attacks
    SecRule REQUEST_URI "@rx (.*)wp-login.php(.*)" deny,nolog
    

    Replace the 1.2.3.4 with your home IP address. You can have multiple lines like this if you access your WordPress site from multiple IP addresses.

  5. Restart Apache:
    $ sudo /etc/init.d/apache2 restart
    
  6. You are done. If you want, you can check your Apache logs to see there’s now 403 error codes being returned for the botnet requests.

The solution isn’t perfect, since you still get lots of “403 – Forbidden” log entries, but it’s better than leaving your WordPress site vulnerable.

Update: after I whitelisted my home IP, the botnet seems to have given up – after about 15 minutes the requests stopped coming.

Update: I posted the question and answer to Stack Overflow, since that will probably get more traffic than this blog post: How do I protect my WordPress/Apache website from a brute-force botnet attack?