前言
最近对自己的博客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
|