April 2024
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
2930  

Categories

April 2024
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
2930  

Mitigate DDoS attack with ngx_http_limit_req_module and fail2ban

Mitigate DDoS attack with ngx_http_limit_req_module and fail2ban

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  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.example.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:

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>