lua+redis实现ip限流cc防护功能

-- cc防护
-- 2020/03/08 11:30
-- 加载并编译外部运行脚本
dofile("../lua/system_conf.lua")
dofile("../lua/function.lua")
local server_name = ngx.var.server_name
local client_ip = get_client_ip()
local ip_block_time = 100 --封禁IP时间(秒)
local ip_time_out = 30 --指定ip访问频率时间段(秒)
local ip_max_count = 20 --指定ip访问频率计数最大值(秒)
local server_name = 'cdn' --nginx的location中定义的业务标识符

--连接redis
local redis = require "resty.redis"
local conn = redis:new()
ok, err = conn:connect(CACHE_SERVER_REDIS_HOST, CACHE_SERVER_REDIS_PORT)
ok, err = conn:auth(CACHE_SERVER_REDIS_PASS)-- pass
conn:set_timeout(2000) --超时时间2秒

--如果连接失败,跳转到脚本结尾
if not ok then

goto FLAG

end

--查询ip是否被禁止访问,如果存在则返回403错误代码
is_block, err = conn:get(server_name.."-BLOCK-"..client_ip)
if is_block == '1' then

ngx.say('<html><h1>11</h1></html>')
do return end
goto FLAG

end

--查询redis中保存的ip的计数器
ip_count, err = conn:get(server_name.."-COUNT-"..client_ip)

if ip_count == ngx.null then --如果不存在,则将该IP存入redis,并将计数器设置为1、该KEY的超时时间为ip_time_out

res, err = conn:set(server_name.."-COUNT-"..client_ip, 1)
res, err = conn:expire(server_name.."-COUNT-"..client_ip, ip_time_out)

else

ip_count = ip_count + 1 --存在则将单位时间内的访问次数加1
if ip_count >= ip_max_count then --如果超过单位时间限制的访问次数,则添加限制访问标识,限制时间为ip_block_time
    res, err = conn:set(server_name.."-BLOCK-"..client_ip, 1)
    res, err = conn:expire(server_name.."-BLOCK-"..client_ip, ip_block_time)
else
    res, err = conn:set(server_name.."-COUNT-"..client_ip,ip_count)
    res, err = conn:expire(server_name.."-COUNT-"..client_ip, ip_time_out)
end

end
-- 结束标记
::FLAG::
local ok, err = conn:close()
ngx.say('success')

发表评论

电子邮件地址不会被公开。 必填项已用*标注