I've been flooded with POST requests at /wp-login.php

Today and in the past few days I’ve been often flooded with POST requests that look like this: - - [02/Sep/2014:18:36:17 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-" - - [02/Sep/2014:18:36:19 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-" - - [02/Sep/2014:18:36:32 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-" - - [02/Sep/2014:18:36:33 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-" - - [02/Sep/2014:18:36:34 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-"

These kind of requests uses significant resources on my server, and the PHP process is constantly using CPU cycles.

I’ve tried manually banning the IP address, but I had no luck. I’ve tried using the ngx_http_limit_req_module, but again no luck. I’ve found a tutorial on how to set-up a fail2ban filter to catch these kind of reqeusts from the access logs, but again no luck.

Today this IP flooded me with over 50.000 reqs and I needed to shut down the server for half an hour so it can stop.

Is there any proper automatic way to set up so the server can detect and block IP adresses that flood the server with requests like these? I don’t want to use wordpress plugins or anything like that, since I have a couple of sites installed and I don’t want to install security plugins to each of them.

Here’s the fail2ban filter I have added:

failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =

And here’s the rule implemented in jail.local

enabled = true
filter = wp-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
maxretry = 2

But I had no luck with this.

Any suggestions?

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

Your fail2ban doesn’t look right. Think you need a log file. I got this from

Hope it helps



enabled = true filter = apache-wplogin action = iptables-multiport [name = apache-wplogin, port = “http, https” protocol = tcp] port = http, https logpath = /var/log/httpd/access_log maxretry = 5 findtime = 60 bantime = 86400



failregex = ^. * “POST. * / wp-login \. php HTTP. * 200e * $
ignoreregex =

Edit I can never get the code blocks to work right :(

I know the OP was from a while ago, but hopefully this will help anyone finding this same issue.

Our solution uses fail2ban like the others, but with actions setup to use ufw commands since we love the simplicity of that firewall. Note that our log file is different from the default and includes the IP address the request was sent to first (other_vhosts_access.log), so remove the first “\S*” and space from regex for the normal access log. For some reason, this was the default when we set up the Wordpress droplet. YMMV.

# cat /etc/fail2ban/action.d/ufw.conf
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny from <ip>
actionunban = ufw delete deny from <ip>

# cat /etc/fail2ban/filter.d/xmlrpc.conf 
failregex = ^\S* <HOST> .*POST .*xmlrpc\.php.*
ignoreregex =

# cat /etc/fail2ban/filter.d/wp-login.conf 
failregex = ^\S* <HOST> .*POST .*wp-login\.php.*
ignoreregex =

# cat /etc/fail2ban/jail.d/xmlrpc.conf 
enabled = true
filter = xmlrpc
action = ufw
logpath = /var/log/apache2/other_vhosts_access.log
bantime = 43200
maxretry = 2

# cat /etc/fail2ban/jail.d/wp-login.conf 
enabled = true
filter = xmlrpc
action = ufw
logpath = /var/log/apache2/other_vhosts_access.log
bantime = 600
maxretry = 6
findtime = 60

No changes were required to Wordpress or any plugins to install. This does mean that fail2ban can’t actually tell if there was a failure, it just looks at how often those URLs were accessed.