The other day I received a lot of alerts from the service I use to monitor the uptime of my blogs, all of them were down without an apparent reason. My blogs are hosted in a virtual private server configured with just a basics configuration, a LAMP server running in Ubuntu, no Webmin, no PhpMyAdmin, just the basic stack. Basics are the best, but that’s a topic for another post.
No worries, I have a solution for these kind of situations…
Yes, I’m not a pro backend developer, and as you can expect, it didn’t work. So I tried another restart. Nothing happened. $#%£!
Yes! I had a problem and I didn’t know a s*** about it. First thing, I connected to the server through SSH and I looked what was happening. It seemed Apache was down just a few seconds after a restart. Something was affecting it.
How did I know what was crashing my Apache? Logs! If something was happening, I’m sure it was written in the logs. So…
$ tail -f /var/log/apache2/access.log
This gave me more information. Somebody was stacking my Apache and crashing it. I was being a victim of an xmlrpc DDOS attack. My logs had a lot of lines like this:
xxx.xxx.xxx.xxx - - [01/Feb/2017:16:33:50 -0500] "POST /xmlrpc.php HTTP/1.0" 200 674 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
I had to put all my knowledge in backend security to work. Battle had started.
I know there are a lot of ways to block this kind of DDoS attacks but I read something about Fail2Ban and I wanted to test it against this thread. Fail2Ban is a tool that reads apache logs and if it detects something weird with an IP it blocks this IP using iptables. I installed it like this:
$ apt-get install fail2ban iptables
Then I created this file /etc/fail2ban/filter.d/wordpress.conf and I put this to create the filter definition:
failregex = ^<HOST> .* "POST .*wp-login.php
^<HOST> .* "POST .*xmlrpc.php
I needed to add the filter to the jail, to do that I created this file /etc/fail2ban/jail.d/wordpress.conf with this information:
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/apache2/access.log
findtime = 3600
bantime = 86400
With that configuration, Fail2Ban will looked in apache2 logs for the filter to match a request every 3600 seconds, if it happened, then the IP would be banned for 86400 seconds using iptables.
That’s all, I just restarted Fail2Ban like this:
$ sudo service fail2ban restart
It didn’t take too much time to start watching logs with IPs banned. Yay!