How To: Stop Apache DOS attacks with Fail2Ban

I had to install and configure fail2ban yesterday to stop some hacking attempts on my FTP server, and when I was looking through the fail2ban configs I saw that you could stop DOS (Denial of Service) attacks with it too. As this site’s been hit by the occasional DOS from people with an axe to grind and too much time on their hands, I thought I may as well set up a DOS mitigation strategy while I was at it. Here’s how:

  1. Install fail2ban through the method of your choice.
  2. Edit the file /etc/fail2ban/jail.local and add the following section:

    Don’t forget to replace YOUR_WEB_SERVER_ACCESS_LOG with the actual access log for your webserver! Note: This doesn’t have to be an apache log, I just happen to be using apache.

  3. Now we need to create the filter file, so create the file /etc/fail2ban/filters.d/http-get-dos.conf and place the following contents in it:

  4. Now we just need to restart fail2ban for the new jail & filter to come into affect:

    Or if your machine is on systemd, use:

    Also on systemd, if you want fail2ban to start on boot (and the chances are that you do), run the additional:

    With all that done your site should be pretty safe from casual DOS attacks, although you’d likely need more stringent maxretry and findtime settings to really help against Distributed DOS (DDOS) attacks.

Testing

To check if fail2ban is seeing the logs, check out /var/log/fail2ban.log and you should see things like:

showing up as visitors view your site.

If you want to test if it’s really working, a nice way to do so is to use ab (Apache Benchmark – part of the apache2-utils package), like this:

This will kick off 500 page-loads in 10 concurrent connections against your site. When the ban kicks in the page-loads will stop (as incoming GET requests from your IP will be dropped), then when the bantime expires you’ll be able to access the site again. If you then take a look in your /var/log/fail2ban.log file you should see something like this:

Pretty neat, huh?

Many thanks to the authors of the following great articles for helping me to get this set up in no-time:
http://www.dedmeet.com/software-projects-mainmenu-12/fail2ban-to-limit-ddos-attacks– on-webserver.html
http://go2linux.garron.me/linux/2011/05/fail2ban-protect-web-server-http-dos-attack-1084.html

Cheers! =D

16 thoughts on “How To: Stop Apache DOS attacks with Fail2Ban”

  1. This is a simple solution, right.

    But what would you do, if u have a website with much content and each item is processed by a simple request, so u have e.g. 20 or more request within few seconds from each user?
    You will be going to drop a lot of users from visiting your site!

  2. Hi,

    Is there anyway to find the optimal values for maxretry and findtime for all DOS attacks ? The default maxretry 300 and findtime 600 doesn’t seems to work most of the time.

    1. I’m not aware of a way to find optimal values beyond trial and error, sorry – although that doesn’t mean there isn’t one.

      Perhaps the fail2ban docs might say something about it?

  3. But why is not working for me? Is it possible to missing some file from fail2ban? The jail is starting, access log is set. Maybe the regex is not right for me? If I hit F5 like crazy nothing happens. Nothing in the fail2ban log.

  4. I have the same problem that Gabo had:

    I seemed to have installed everything and configured all the config files file (keeping in mind to set the log file location), but it doesn’t seem to log or block(?) DDOS attacks?

    I used the exact filter stated above. I am sure the jail is nominally working because I get:

    [root@myhost filter.d]# fail2ban-client status
    Status
    |- Number of jail: 2
    `- Jail list: http-get-dos, sshd

    But when I try the ab command, none of the requests are blocked, and nothing is logged in the log file. Any ideas, please?

    1. Hmm, perhaps look at:
      – Are the page gets showing up in your apache log? i.e. is every page GET being logged?
      – Are permissions on the log file such that it can be read?
      – Perhaps try a more stringent maxretry to make sure you’re hitting the limit?

  5. Hi. Thanks for your reply. I’ve solved it.

    For your readers:

    I mistakenly thought the log file in the jail.local file was the output log file for fail2ban. Instead, it’s the input log file that fail2ban needs in order to make rules.

    So first I changed it to /var/log/apache_access.log, and that didn’t work. But then I realised that we configured apache to log to another file.

    Once I had the correct log file, it worked beautifully. Thanks!

Leave a Reply

Your email address will not be published.