Today and in the past few days I’ve been often flooded with POST requests that look like this:
181.165.120.195 - - [02/Sep/2014:18:36:17 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-"
181.165.120.195 - - [02/Sep/2014:18:36:19 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-"
181.165.120.195 - - [02/Sep/2014:18:36:32 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-"
181.165.120.195 - - [02/Sep/2014:18:36:33 +0200] "POST /wp-login.php HTTP/1.0" 302 0 "-" "-"
181.165.120.195 - - [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:
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =
And here’s the rule implemented in jail.local
[wp-auth]
enabled = true
filter = wp-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
maxretry = 2
But I had no luck with this.
Any suggestions?
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!
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
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny from <ip>
actionunban = ufw delete deny from <ip>
# cat /etc/fail2ban/filter.d/xmlrpc.conf
[Definition]
failregex = ^\S* <HOST> .*POST .*xmlrpc\.php.*
ignoreregex =
# cat /etc/fail2ban/filter.d/wp-login.conf
[Definition]
failregex = ^\S* <HOST> .*POST .*wp-login\.php.*
ignoreregex =
# cat /etc/fail2ban/jail.d/xmlrpc.conf
[xmlrpc]
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
[wp-login]
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.
HTH
Sources:
You can deny the IP address using a firewall. If you’re on Ubuntu I’d suggest using UFW as a frontend to IPTables.
First set up some basic rules that will open port 22 for SSH and port 80 for HTTP while denying any incoming requests for other ports:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
Then, set a rule that will deny all requests from the IP address:
sudo ufw insert 1 deny from 181.165.120.195
Finally, enable the firewall:
sudo ufw enable
Your fail2ban doesn’t look right. Think you need a log file. I got this from http://en.alexnogard.com/securing-wordpress-using-fail2ban-wp-login/
Hope it helps
[Apache-wplogin]
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
/etc/fail2ban/filter.d/apache-wplong.conf
[Définition]
failregex = ^. * “POST. * / wp-login \. php HTTP. * 200e * $
ignoreregex =
Edit I can never get the code blocks to work right :(
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.