-- cc防护
    -- 2020/03/08 11:30
    -- @yunhai
    -- 加载并编译外部运行脚本 
    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')
最后修改:2021 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏