Like most people that run a WordPress site, or any CMS, I’ve struggled with brute force attacks on my site. Having just installed fail2ban on a mail server, this seemed like an obvious. Thankfully, as well, someone had already written a plugin for WordPress to drop a message in the system log saying a login failed (by default, Apache doesn’t do this, it just shows someone hit the login page). At first, I had set up an iptables/pf rule to block the bad user, but for some reason, this wasn’t happening. My test browser kept hitting the page successfully.
After a break, I realized that I use Cloudflare, and of course blocking the offending IP wouldn’t work… it never actually connects to my host. Thankfully, Cloudflare has an API, and there was already a starting point for a fail2ban action, albeit, out of date (Cloudflare forces json now). Below is that action. You should be able to just call this like any other action, after you fill out the appropriate “token” and “email”.1
Good luck!
# Fail2Ban cloudflare action
#
# Author: Ryan Stasel
#
# $Revision$
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = curl -s https://www.cloudflare.com/api_json.html -d ‘a=ban’ -d ‘key=
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = curl -s https://www.cloudflare.com/api_json.html -d ‘a=nul’ -d ‘key=
[Init]
account = YOUR_CLOUDFLARE_EMAIL
token = YOUR_CLOUDFLARE_TOKEN
- Note: I had to disable “always online” with Cloudflare to have the block take effect within 5-10 seconds. With “always online” enabled, it took about 2-3 minutes to block the attack, all the while the “bot” was able to keep hitting my server. [↩]