How to Implement Dynamic IP Blocking in Nginx: 3 Proven Methods
This guide explains three practical ways to achieve dynamic IP blocking in Nginx—using Fail2ban, Lua with Redis, and Nginx's built‑in limit modules—detailing configuration steps, code examples, advantages, drawbacks, and best‑practice recommendations for various deployment scenarios.
Common Dynamic IP Blocking Solutions
The article compares three mainstream methods for dynamic IP blocking in Nginx: Fail2ban, Nginx Lua + Redis, and Nginx built‑in limit modules, outlining their implementation steps, strengths, weaknesses, and suitable use cases.
1. Fail2ban Dynamic Blocking
Fail2ban monitors Nginx logs for error codes (e.g., 403/401/404) or excessive request rates, then automatically adds offending IPs to iptables or
firewalld>.</p>
<ol>
<li><strong>Install Fail2ban</strong>
<pre><code>sudo apt-get install fail2ban # Debian/Ubuntu
sudo yum install fail2ban # CentOS/RHELConfigure Nginx Log Format <code>log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main;</code> Create Fail2ban Filter <code>[Definition] failregex = ^<HOST> -.*"(GET|POST).*HTTP.*" 403 ignoreregex =</code> Configure Jail <code>[nginx-cc] enabled = true port = http,https filter = nginx-cc logpath = /var/log/nginx/access.log maxretry = 100 findtime = 60 bantime = 3600 action = iptables[name=NGINX, port=http, protocol=tcp]</code> Enable and Start Service <code>sudo systemctl enable fail2ban sudo systemctl restart fail2ban</code>
2. Nginx Lua + Redis Real‑Time Blacklist
This approach requires OpenResty (Nginx + LuaJIT). A Lua script queries Redis for a blacklist during the request phase, providing high‑performance, distributed blocking.
Install OpenResty
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openrestyConfigure Nginx
http {
lua_shared_dict ip_blacklist 10m;
server {
listen 80;
location / {
access_by_lua_file /etc/nginx/lua/ip_blacklist.lua;
}
}
}Lua Script (/etc/nginx/lua/ip_blacklist.lua)
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "Redis connection failed: ", err)
return
end
local client_ip = ngx.var.remote_addr
local is_banned = red:sismember("ip_blacklist", client_ip)
if is_banned == 1 then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
red:set_keepalive(10000, 100)Manage Blacklist in Redis
redis-cli SADD ip_blacklist 192.168.1.100 # block
redis-cli SREM ip_blacklist 192.168.1.100 # unblock3. Nginx Built‑in Rate Limiting Modules
Nginx provides limit_req_zone and limit_conn_zone to restrict request rates and concurrent connections. While they do not perform true IP bans, they effectively mitigate CC attacks.
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
limit_req zone=req_limit burst=20 nodelay;
limit_conn conn_limit 10;
}
}
}When the limit is exceeded, Nginx returns 503 Service Temporarily Unavailable .
Practical Tips and Caveats
Obtain Real Client IP
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;Combine Techniques for Best Protection
Fail2ban → bans malicious IPs based on log patterns.
Nginx built‑in limits → blocks burst traffic instantly.
Lua + Redis → shares a real‑time blacklist across distributed nodes.
Layered Blocking Strategy
Instant protection: limit_req / limit_conn.
Short‑term ban: Fail2ban (minutes to hours).
Long‑term/global ban: Lua + Redis (days or permanent).
Conclusion and Recommended Deployment
For single‑server environments, combine Fail2ban with Nginx's native rate limiting. For distributed, high‑traffic systems, adopt the Lua + Redis solution together with built‑in limits to achieve fast, scalable, and maintainable IP blocking.
Ray's Galactic Tech
Practice together, never alone. We cover programming languages, development tools, learning methods, and pitfall notes. We simplify complex topics, guiding you from beginner to advanced. Weekly practical content—let's grow together!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
