收录拒绝指定ip请求黑名单lua脚本、拒绝ip频次请求的lua脚本

前言

最近对自己的博客EAMON (eamonjun.cn)加了个功能,基于OpenResty + Redis 动态封禁ip.

关于OpenResty了解一下,OpenResty(又称:ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台,由中国人章亦春发起,提供了很多高质量的第三方模块。

说实话对于lua脚本看是能看的懂的或者在一个成熟的脚本上做一些小的修改,但是全程写下来就有点费劲了,所以需要收集一些常用的脚本,以备不时之需。

lua脚本

拒绝指定ip请求黑名单lua脚本

local redis_host ="IP地址"
local redis_port ="端口号"

--connection timeout for redis In ms. don't set this too high!
local redis_connection_timeout = 1000

--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     = ngx.shared.ip_blacklist
local last_update_time = ip_blacklist:get("last_update_time");


--only update ip_blacklist from Redis once every cache_ttl seconds:
if last_update_time == nil or last_update_time <(ngx.now() - cache_ttl) then
    local redis  = require('resty.redis');
    local red    = redis:new();
    red:set_timeout(redis_connection_timeout);
  
    local ok, err = red:connect(redis_host,redis_port);
    if not ok then
        ngx.log(ngx.DEBUG, "Redis connection error while retrieving ip_blacklist: ".. err);
    else
        local new_ip_blacklist, err = red:smembers(redis_key);
        if err then
            ngx.log(ngx.DEBUG, "Redis read error while retrieving ip_blacklist: "..err);
        else
            --replace the locally stored ip blacklist with the updated values
            ip_blacklist:flush_all();
            for index, banned_ip in ipairs(new_ip_blacklist) do
                ip_blacklist:set(banned_ip, true);
	        end 
             --update time
            ip_blacklist:set("last_update_time", ngx.now());
        end
    end
end

if ip_blacklist:get(ip) then
    ngx.log(ngx.DEBUG,"Banned IP detected and refused access: " .. ip);
    return ngx.exit(403);
end	

 拒绝ip频次请求的lua脚本

# Lua 
local function close_redis(redcli) 
    if not redcli then 
        return 
    end 
    --释放连接(连接池实现) 
    local pool_max_idle_time = 10000 --毫秒 
    local pool_size = 100 --连接池大小 
    local ok, err = redcli:set_keepalive(pool_max_idle_time, pool_size) 
 
    if not ok then 
        ngx_log(ngx_ERR, "set redis keepalive error : ", err) 
    end 
end 
 
-- 连接redis 
local redis = require('resty.redis') 
local redcli = redis.new() 
redcli:set_timeout(1000) 
 
local ip = "ip地址"
local port = "端口号" 
local ok, err = redcli:connect(ip,port) 
if not ok then 
    return close_redis(redcli) 
end 
 
local clientIP = ngx.var.remote_addr 
 
-- increKey为请求频率,blackKey黑名单key 
local incrKey = "user:"..clientIP..":request:frequency" 
local blackKey = "user:"..clientIP..":black:list" 
 
local is_black,err = redcli:get(blackKey) 
 
if tonumber(is_black) == 1 then 
    ngx.exit(403) 
    close_redis(redcli) 
end 
 
inc  = redcli:incr(incrKey) 
new_ip_blacklist = redcli:smembers("ip_blacklist")
ngx.say(inc) 
ngx.say(new_ip_blacklist)
 
if inc < 2 then 
   inc = redcli:expire(incrKey,1) 
end 
 
if inc > 2 then --每秒2次以上访问即视为非法,会阻止30s的访问 
    redcli:set(blackKey,1) 
    redcli:expire(blackKey,30) 
end 
 
close_redis(redcli) 

(一)闲来无聊,去搭了个人博客网站_Eamon_Jun的博客-CSDN博客 

(二)购买域名和ICP备案的流程以及遇到的问题

 参考文章:                                             

 https://blog.csdn.net/weixin_43112000/article/details/86650107   

 https://www.sohu.com/a/276817238_468627


版权声明:本文为m17601624170原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。