Nginx’s limit_req slows down or rejects request floods and logs a limiting requests line to
the error log. The nginx-limit-req filter turns those log lines into bans — so persistent
abusers get firewalled, not just throttled.
1. Configure limit_req in Nginx
In http {} (e.g. /etc/nginx/nginx.conf):
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
In the server {} / location {} you want to protect:
location / {
limit_req zone=req_limit burst=20 nodelay;
# ... your existing config ...
}
Reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
2. The Fail2ban jail
In /etc/fail2ban/jail.local:
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 5m
bantime = 1h
3. Reload Fail2ban and verify
sudo fail2ban-client reload
fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-limit-req.conf
sudo fail2ban-client status nginx-limit-req
How they divide the work: limit_req handles short bursts in real time; Fail2ban bans the IPs
that keep tripping it, so they stop consuming worker connections entirely. Tune rate/burst
for normal users first, then set maxretry for how much abuse you’ll tolerate before a ban.