Implementing a Dynamic IP Blacklist with Nginx, Lua, and Redis
This guide explains how to build a dynamic IP blacklist using Nginx, Lua, and Redis, covering installation of LuaJIT, compiling Nginx with required modules, configuring Redis, writing Lua access‑limit scripts, and verifying that frequent requests are automatically blocked for a set period.
To prevent malicious crawlers or abusive users from accessing a server, a dynamic IP blacklist is required that rejects requests from IPs listed in the blacklist.
There are several ways to implement an IP blacklist: configuring iptables at the OS level, using Nginx's deny directive or Lua plugins, or checking the client IP in the application layer. This article adopts the Nginx + Lua + Redis architecture to create a Web Application Firewall (WAF) that dynamically blocks frequent IPs.
Install LuaJIT :
[root@hd03 ~]# tar -xf LuaJIT-2.0.5.tar.gz -C /opt/ [root@hd03 ~]# cd /opt/LuaJIT-2.0.5/[root@hd03 LuaJIT-2.0.5]# make && make installSet environment variables:
export LUAJIT_LIB=/usr/local/lib export LUAJIT_INC=/usr/local/include/luajit-2.0Source the profile and create a symlink for the shared library.
[root@hd03 LuaJIT-2.0.5]# source ~/.bash_profile [root@hd03 LuaJIT-2.0.5]# ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2Compile Nginx with required modules (including Lua and Redis support):
[root@hd03 ~]# tar -xf nginx-1.20.2.tar.gz -C /opt/ [root@hd03 nginx-1.20.2]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/bin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/run/nginx.lock --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --http-client-body-temp-path=/var/cache/client_temp --http-proxy-temp-path=/var/cache/proxy_temp --http-fastcgi-temp-path=/var/cache/fastcgi_temp --http-uwsgi-temp-path=/var/cache/uwsgi_temp --http-scgi-temp-path=/var/cache/scgi_temp --with-http_v2_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-threads --with-stream --with-stream_ssl_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --add-module=/usr/local/ngx_devel_kit-0.3.0 --add-module=/usr/local/lua-nginx-module-0.10.13[root@hd03 nginx-1.20.2]# make && make install [root@hd03 nginx-1.20.2]# ln -s /usr/local/nginx/bin/nginx /usr/bin/Start Nginx: [root@hd03 nginx-1.20.2]# nginx Deploy the WAF components :
Install lua-resty-redis module:
[root@hd03 ~]# cd /usr/local/lua-resty-redis [root@hd03 lua-resty-redis]# make && make installInstall and configure Redis : [root@hd03 ~]# yum install redis -y Modify /etc/redis.conf (example settings):
bind 0.0.0.0 daemonize yes logfile /var/log/redis/redis.log requirepass 123456 dir /data/redisUpdate Nginx configuration to use the WAF :
lua_shared_dict limit 8m; lua_package_path "lua;/usr/local/nginx/conf/waf/redis.lua;;";Create access_limit.lua (the script checks request frequency, stores counters in Redis, and adds offending IPs to the blacklist).
Place the script in /usr/local/nginx/conf/waf and test the configuration: [root@hd03 waf]# nginx -t Result:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successfulReload Nginx: [root@hd03 waf]# nginx -s reload When a client refreshes the site more than 10 times within one minute, the IP is cached in Redis and automatically blocked for 5 minutes, returning a 403 status code.
Verify in Redis:
Check request count:
redis-cli -h 192.167.16.8 -a 123456 get USER-COUNT-192.167.16.8→ "9" (means 9 hits cached).
Retrieve blacklist set: smembers limit:ip:blacklist → "192.167.16.8".
Manually add an IP to the blacklist: sadd limit:ip:blacklist 192.167.16.8 This completes the end‑to‑end setup of a dynamic IP blacklist using Nginx, Lua, and Redis.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Practical DevOps Architecture
Hands‑on DevOps operations using Docker, K8s, Jenkins, and Ansible—empowering ops professionals to grow together through sharing, discussion, knowledge consolidation, and continuous improvement.
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.
