So, there’s finally been a bit of chatter about an attack that’s been ongoing across many webhosts for a few weeks. The most effective solutions that I’ve seen involve identifying patterns in the nefarious traffic, and blocking based on that. Something like this mod_security rule:
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:5000134
<Locationmatch “/wp-login.php”>
# Setup brute force detection.
# React if block flag has been set.
SecRule user:bf_block “@gt 0? “deny,status:401,log,id:5000135,msg:’ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.’”
# Setup Tracking. On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS “^302? “phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000136?
SecRule RESPONSE_STATUS “^200? “phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137?
SecRule ip:bf_counter “@gt 10? “t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0?
</locationmatch>
— Source LiquidWeb
If you fail your login more than 10 times, you get blocked.
The problem always is that your attackers will adjust. The most effective avoidance of the atttack that I’ve seen? Just block all traffic.
In your apache conf file (or in the pre-virtual-host for cPanel users, to ensure it gets retained through apache config rebuilds),
<Files wp-login.php>
# set up rule order
order deny,allow
# default deny
deny from all
# Add additional IPs for access here
# And then allow ip, or ranges of IPs, as in the examples below:
# allow from 10.10.4.0/23
# allow from 10.30.6.17
errordocument 401 default
errordocument 403 default
errordocument 404 default
</Files>
It’s a pain in the behind to add all of your customers manually, but it’s better than your server not being online. I promise.