Nginx Anti-DOS filter for Fail2Ban

We are currently trying out this Fail2Ban rule on one of our server, to block simple (but very upsetting) DOS attacks on Nginx automatically (after 30 seconds).

New filter in /etc/fail2ban/filter.d/nginx-dos.conf:

# Fail2Ban configuration file
# Generated on Fri Jun 08 12:09:15 EST 2012 by BeezNest
# Author: Yannick Warnier
# $Revision: 1 $

# Option:  failregex
# Notes.:  Regexp to catch a generic call from an IP address.
# Values:  TEXT
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
ignoreregex =

In our jail.local, we have (at the end of the file):

# Based on apache-badbots but a simple IP check (any IP requesting more than
# 240 pages in 60 seconds, or 4p/s average, is suspicious)
# Block for two full days.
# @author Yannick Warnier
enabled = true
port    = http,8090
filter  = nginx-dos
logpath = /var/log/nginx/*-access.log
findtime = 60
bantime  = 172800
maxretry = 240

Of course, in case you would be logging all resources of your site (images, css, js, etc), it would be really easy to get to those numbers as a normal user. To avoid this, use the access_log off directive of Nginx, like so:

 # Serve static files directly
        location ~* .(png|jpe?g|gif|ico)$ {
                expires 1y;
                access_log off;
                try_files $uri $uri/ @rewrite;
                gzip off;
        location ~* .(mp3)$ {
                expires 1y;
                access_log off;
                gzip off;
        location ~* .(css)$ {
                expires 1d;
                access_log off;
        location ~* .(js)$ {
                expires 1h;
                access_log off;

We’ll see how that works for us… (and report here)

It's only fair to share...Share on Facebook
Tweet about this on Twitter
Share on LinkedIn
Share on Tumblr
Email this to someone


  1. hi, for apache how to do it to bypass images, css…? then, i have /var/log/httpd/sb-access_log is that correct to use? OR *access_log at the end is correct? thanks

Leave a Reply

Your email address will not be published. Required fields are marked *