Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Redis based IP blacklist for Nginx (LUA)
-- a quick LUA access script for nginx to check IP addresses against an
-- `ip_blacklist` set in Redis, and if a match is found send a HTTP 403.
-- allows for a common blacklist to be shared between a bunch of nginx
-- web servers using a remote redis instance. lookups are cached for a
-- configurable period of time.
-- block an ip:
-- redis-cli SADD ip_blacklist
-- remove an ip:
-- redis-cli SREM ip_blacklist
-- also requires lua-resty-redis from:
-- your nginx http context should contain something similar to the
-- below: (assumes resty/redis.lua exists in /etc/nginx/lua/)
-- lua_package_path "/etc/nginx/lua/?.lua;;";
-- lua_shared_dict ip_blacklist_cache 10m;
-- you can then use the below (adjust path where necessary) to check
-- against the blacklist in a http, server, location, if context:
-- access_by_lua_file /etc/nginx/lua/ip_blacklist.lua;
-- chris boulton, @surfichris
local redis_host = ""
local redis_port = 6379
-- connection timeout for redis in ms. don't set this too high!
local redis_timeout = 200
-- check a set with this key for blacklist entries
local redis_key = "ip_blacklist"
-- cache lookups for this many seconds
local cache_ttl = 60
-- end configuration
local ip = ngx.var.remote_addr
local ip_blacklist_cache = ngx.shared.ip_blacklist_cache
-- setup a local cache
if cache_ttl > 0 then
-- lookup the value in the cache
local cache_result = ip_blacklist_cache:get(ip)
if cache_result then
ngx.log(ngx.DEBUG, "ip_blacklist: found result in cache for "..ip.." -> "..cache_result)
if cache_result == 0 then
ngx.log(ngx.DEBUG, "ip_blacklist: (cache) no result found for "..ip)
ngx.log(ngx.INFO, "ip_blacklist: (cache) "..ip.." is blacklisted")
return ngx.exit(ngx.HTTP_FORBIDDEN)
-- lookup against redis
local resty = require "resty.redis"
local redis = resty:new()
local connected, err = redis:connect(redis_host, redis_port)
if not connected then
ngx.log(ngx.ERR, "ip_blacklist: could not connect to redis @"..redis_host..": "..err)
local result, err = redis:sismember("ip_blacklist", ip)
if not result then
ngx.log(ngx.ERR, "ip_blacklist: lookup failed for "..ip..":"..err)
-- cache the result from redis
if cache_ttl > 0 then
ip_blacklist_cache:set(ip, result, cache_ttl)
redis:set_keepalive(10000, 2)
if result == 0 then
ngx.log(ngx.INFO, "ip_blacklist: no result found for "..ip)
ngx.log(ngx.INFO, "ip_blacklist: "..ip.." is blacklisted")
return ngx.exit(ngx.HTTP_FORBIDDEN)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment