lua + redis 实现动态ip黑名单

本文介绍如何使用Lua脚本结合Nginx和Redis实现动态IP黑名单功能,通过定时从Redis同步黑名单至Nginx本地缓存,以提高访问控制效率并减少延迟。文章详细解释了代码逻辑,包括IP获取、缓存刷新和错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

lua_shared_dict shared_ip_blacklist 1m; #定义ip_blacklist 本地缓存变量

location /ipblacklist {
    access_by_lua_file /usr/local/lua/access_by_limit_ip.lua;
    echo "ipblacklist";
}

local function close_redis(red)  
    if not red then  
        return
    end  
    --释放连接(连接池实现)  
    local pool_max_idle_time = 10000 --毫秒  
    local pool_size = 100 --连接池大小  
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)  
    if not ok then  
        ngx.say("set keepalive error : ", err)  
    end  
end

local function errlog(...)
    ngx.log(ngx.ERR, "redis: ", ...)
end

local function duglog(...)
    ngx.log(ngx.DEBUG, "redis: ", ...)
end

local function getIp()
    local myIP = ngx.req.get_headers()["X-Real-IP"]
    if myIP == nil then
        myIP = ngx.req.get_headers()["x_forwarded_for"]
    end
    if myIP == nil then
        myIP = ngx.var.remote_addr
    end
    return myIP;
end

local key = "limit:ip:blacklist"
local ip = getIp();
local shared_ip_blacklist = ngx.shared.shared_ip_blacklist

--获得本地缓存的最新刷新时间
local last_update_time = shared_ip_blacklist:get("last_update_time");

if last_update_time ~= nil then 
    local dif_time = ngx.now() - last_update_time 
    if dif_time < 60 then --缓存1分钟,没有过期
        if shared_ip_blacklist:get(ip) then
            return ngx.exit(ngx.HTTP_FORBIDDEN) --直接返回403
        end
        return
    end
end

local redis = require "resty.redis"  --引入redis模块
local red = redis:new()  --创建一个对象,注意是用冒号调用的

--设置超时(毫秒)  
red:set_timeout(1000) 
--建立连接  
local ip = "192.168.5.202"  
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then  
    close_redis(red)
    errlog("limit ip cannot connect redis");
else
    local ip_blacklist, err = red:smembers(key);
    
    if err then
        errlog("limit ip smembers");
    else
        --刷新本地缓存,重新设置
        shared_ip_blacklist:flush_all();
        
        --同步redis黑名单 到 本地缓存
        for i,bip in ipairs(ip_blacklist) do
            --本地缓存redis中的黑名单
            shared_ip_blacklist:set(bip,true);
        end
        --设置本地缓存的最新更新时间
        shared_ip_blacklist:set("last_update_time",ngx.now());
    end
end  

if shared_ip_blacklist:get(ip) then
    return ngx.exit(ngx.HTTP_FORBIDDEN) --直接返回403
end
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值