Securing NGINX with Limit Req Module and Fail2Ban on Centos 7

The ngx_http_limit_req_module module allows you to limit the speed of processing requests for a given key, or, as a special case, the speed of processing requests from one IP address.

Operating principle

Nginx’s Limit Req Module limits the maximum number of requests from one IP and writes information to the error.logFail2Ban reads data from the error.log and blocks the IP that has exceeded the request limit.

Configuring NGINX

NGINX installation was covered earlier

First, let’s configure Nginx to limit the number of requests from one IP address using Nginx’s Limit Req Module.

Opening the file /etc/nginx/nginx.conf (for all sites on the server) and in the block http {…} add the line:

http {
...
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
...
}
  • $ binary_remote_addr – Nginx variable containing the IP from which the request came;
  • zone = one – zone name. If configuration is done in several vhost files, the names must be different;
  • 10m is the size of the zone. 1m can contain 16000 states, i.e. 16,000 unique IP addresses;
  • rate = 1r / s – 1 request per second allowed. You can also specify the number of requests per minute (30r / m – 30 requests per minute)

If you are using virtual hosts, the line limit_req_zone must be written outside the block server {…}

Now for our host in the block server {…} add the line:

limit_req   zone=one  burst=1 nodelay;
  • one – the name of the zone configured above;
  • burst – maximum burst of activity, you can adjust to what value of requests per second the burst of requests can be;
  • nodelay – immediately, upon reaching the connection limit, issue a 503 (Service Unavailable) code for this IP

An example of a config for requests to php files:

...
location ~ .php$ {
  limit_req   zone=one  burst=1 nodelay;
  include fastcgi_params;
  fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
}
...

Configuring Fail2Ban

Installing Fail2Ban was covered earlier

Let’s edit the file /etc/fail2ban/jail.local, add the lines at the very end of the file:

[nginx-limit-req]
enabled = true
filter  = nginx-limit-req
port    = http,https
logpath = /var/log/nginx/*error.log
bantime = 600
maxretry = 5
  • enabled – enable or disable the rule
  • logpath – the path to the logs, if you use virtual hosts and the logs are stored elsewhere, you must write the appropriate path
  • filter – filter name (taken from the /etc/fail2ban/filter.d/ directory)
  • maxretry – the number of entries in the error log for one IP
  • bantime – ip blocking time, in seconds

Reload Fail2Ban:

[[email protected]]# systemctl restart fail2ban

or re-read the configuration files

[[email protected]]# fail2ban-client reload

View information about blocked IP

[[email protected]]# fail2ban-client status nginx-limit-req

Other rules for Fail2Ban

Blocking bots

Go to the catalog /etc/fail2ban/filter.d/ and copy the filter for Apache

[[email protected]]# cd /etc/fail2ban/filter.d/
[[email protected]]# cp apache-badbots.conf nginx-badbots.conf

Editing the file /etc/fail2ban/jail.local, add the lines:

[nginx-badbots]
enabled  = true
filter   = nginx-badbots
port     = http,https
logpath  = /var/log/nginx/access.log
bantime  = 600
maxretry = 2

This filter is banned by userugent

Do not forget to specify the correct path for the logpath

Block IPs that access scripts

Go to the catalog /etc/fail2ban/filter.d/ and create a file nginx-noscript.conf

[[email protected]]# nano /etc/fail2ban/filter.d/nginx-noscript.conf
[Definition]
failregex = ^<HOST> -.*GET.*(.php|.asp|.exe|.pl|.cgi|.scgi)
ignoreregex =

Next, we edit the file /etc/fail2ban/jail.local, add the lines:

[nginx-noscript]
enabled  = true
filter   = nginx-noscript
port     = http,https
logpath  = /var/log/nginx/access.log
bantime  = 600
maxretry = 6

The filter blocks ip that directly access scripts with the php, asp, exe, pl, cgi, scgi extension

Noproxy filter

Go to the catalog /etc/fail2ban/filter.d/ and create a file nginx-noproxy.conf

[[email protected]]# nano /etc/fail2ban/filter.d/nginx-noproxy.conf
[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =

Next, we edit the file /etc/fail2ban/jail.local, add the lines:

[nginx-noproxy]
enabled  = true
filter   = nginx-noproxy
port     = http,https
logpath  = /var/log/nginx/access.log
bantime  = 600
maxretry = 2

Connect filter

Go to the catalog /etc/fail2ban/filter.d/ and create a file nginx-noconnect.conf

[[email protected]]# nano /etc/fail2ban/filter.d/nginx-noconnect.conf
[Definition]
failregex = ^<HOST> -.*CONNECT
ignoreregex =

Next, we edit the file /etc/fail2ban/jail.local, add the lines:

[nginx-noconnect]
enabled  = true
filter   = nginx-noconnect
port     = http,https
logpath  = /var/log/nginx/access.log
bantime  = 600
maxretry = 2

Filter blocks IPs that use Connect method

After adding filters, reload fail2ban and check the status

[[email protected]]# fail2ban-client restart
[[email protected]]# fail2ban-client status

To view information on blocked ip by filters, use the command

[[email protected]]# fail2ban-client status %filter%

where% filter% is the name of the filter

For example, for the nginx-badbots filter, the command will look like:

[[email protected]]# fail2ban-client status nginx-badbots

To unban an IP, you can use the command

[[email protected]]# fail2ban-client set nginx-badbots unbanip 8.8.8.8
Sidebar