The fail2ban do have comprehensive collection of scripts that scan log files and ban IPs that match malicious activities. But we are going to look on how to use ngx_http_limit_req_module logs to ban IPs that shows sign of Distributed Denial of Service (DDoS) attack on your website.
It is assumed in this tutorial that Nginx server is installed in your server. The following procedures are tested on my Linode server running Centos 7 64-bit Linux distribution.
- Enable ngx_http_limit_req_module by adding the following script in your Nginx configuration:
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; ... server { ... limit_req zone=one burst=5; } }
- Restart Nginx server:
systemctl restart nginx.service
You will see entry something like this in Nginx error log if there's abuse detected:
2015/08/27 02:18:05 [error] 21235#21235: *326 limiting requests, excess: 5.297 by zone "one", client: 91.214.169.44, server: www.webfoobar.com, request: "GET /node/8 HTTP/1.1", host: "www.webfoobar.com", referrer: "https://www.webfoobar.com/archive/201502"
We will use this sample log entry for our fail2ban filter script.
- Install fail2ban:
yum install -y fail2ban
- Create fail2ban filter script based on the Nginx error log entry:
vi /etc/fail2ban/filter.d/nginx-ddos.conf
The content of this filter file:
[Definition] failregex = limiting requests, excess:.* by zone.*client:
ignoreregex = - We will use the /etc/hosts.deny to block the IP of the DDoS attacker so we will need to create new fail2ban action script:
vi /etc/fail2ban/action.d/hostsdeny.conf
Add the following script as its content:
[Definition] actionstart = actionstop = actioncheck = actionban = IP=
&& printf %%b " : $IP\n" >> actionunban = IP= && sed -i.old /ALL:\ $IP/d [Init] file = /etc/hosts.deny daemon_list = ALL - Enable the newly created fail2ban filter:
vi /etc/fail2ban/jail.local
Append the following script:
[nginx-ddos] enabled = true port = http,https banaction = hostsdeny findtime = 120 bantime = 7200 maxretry = 30 logpath = %(nginx_error_log)s
- Start the fail2ban service:
systemctl start fail2ban systemctl enable fail2ban.service systemctl list-unit-files | grep fail2ban
- To check the status of this fail2ban filter:
fail2ban-client status nginx-ddos
You will see something like this:
Status for the jail: nginx-ddos |- Filter | |- Currently failed: 18 | |- Total failed: 770 | `- File list: /var/log/nginx/nginx_error_log `- Actions |- Currently banned: 1 |- Total banned: 8 `- Banned IP list: 91.214.169.44
- To test if the fail2ban nginx-ddos filter working:
fail2ban-regex /var/log/nginx/nginx_error_log /etc/fail2ban/filter.d/nginx-ddos.conf
- You can use apache-bench to test the whole system:
ab -n 20 -c 10 http://www.webfoobar.com
Execute the following command to monitor the fail2ban log:
watch -n 1 tail -n 20 /var/log/fail2ban.log
And you will something like this while testing with apache-bench:
2015-08-29 09:56:45,535 fail2ban.filter [16931]: INFO [nginx-ddos] Found 112.209.203.176 2015-08-29 09:56:45,536 fail2ban.filter [16931]: INFO [nginx-ddos] Found 112.209.203.176 2015-08-29 09:56:45,537 fail2ban.filter [16931]: INFO [nginx-ddos] Found 112.209.203.176 2015-08-29 09:56:45,538 fail2ban.filter [16931]: INFO [nginx-ddos] Found 112.209.203.176
Comments
admin
Thu, 12/03/2020 - 07:09
In reply to Many thanks for a complete, yet brief tutorial! by Gwyneth Llewelyn (not verified)
You're welcome
I'm glad the article helped.
good tutorial
Very good, works fine, thank you for taking the time to share this fail2ban tutorial on the internet
Many thanks for a complete, yet brief tutorial!
I landed on your website while searching for instructions on how to properly configure
limit_req_zone
; I have it enabled on my own server, but apparently, it was being too permissive, and I needed to understand how to tweak it to stop those bots, crawlers, and fake login attempts/fake REST calls to grab so many resources (without banning them!).To my delight, you not only explain that thoroughly, but you add, as a bonus, full integration with
fail2ban
! Ironically, I havefail2ban
activated, and I even had the skeleton of a filter to look through the logs in a way very similar to yours, but... that filter wasn't even active and needed some hard kicking to do its job properly...Thanks to this article, now I understand why
fail2ban
was not really doing much about those excessive requests. Every day I had to log in manually and (temporarily) ban all abusive requests. Obviously, I wouldn't catch them all — that's why we have cool things such asfail2ban
. But it's important to understand how these tools actually work together to do its magic.Again, my heartfelt thanks for pointing me in the right direction! I've learned quite a lot today, just from reading this...