Rootop 服务器运维与web架构

基于openresty实现防CC攻击脚本

ngx.header.content_type="text/html;charset=utf8"

-- redis中key失效时间,做为单位时间内访问次数统计。
timeout = 60

-- 超过阀值,阻断时间,单位秒(等于将key失效时间延长)
blocktime = 120

-- 计数阀值,单位时间内请求次数限制
countper = 10

-- 配置token字段(唯一的字段,可以是其他字符。)从哪里获取。1 header, 2 post参数(需要 MIME type application/x-www-form-urlencoded)
tokenfrom = 2

-- 唯一字段名称
uniquestr = 'token'


if tokenfrom == 1 then
    token,e = ngx.req.get_headers()[uniquestr]
else if tokenfrom == 2 then
    ngx.req.read_body()
    token,e = ngx.req.get_post_args()[uniquestr]
    end
end

-- 这里用于处理不带token字段、或者token字段为空的时候不进行防护处理。
-- 比如接口和页面共存的时候 js\css\jpg等资源文件是不含token的。
if token == nil then
    ngx.exec("@php")
else
    if token == "" then
        ngx.exec("@php")
    end
end

redis = require("resty.redis")
red = redis:new()
red:set_timeout(1000)
ok,err = red:connect('127.0.0.1','6379')

if not ok then
    ngx.say('redis connect failed',err)
end

-- redis 认证,如果空密码则注释掉
--ok,err = red:auth('123')
--if not ok then
--    ngx.say('auth failed:',err)
--end

-- redis 切换库
--ok, err = red:select(1)
--if not ok then
--    ngx.say("failed to select db: ", err)
--end

get,e = red:get(token)

if get ~= ngx.null then
    get = tonumber(get)
    if get >= countper then
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end
    count = get + 1
    e = red:ttl(token)
    red:set(token, count)
    red:expire(token, e)

    if count == countper then
       red:expire(token, blocktime)
    end
else
    red:set(token, 1)
    red:expire(token, timeout)
end

ok, err = red:close()

ngx.exec("@php")

@php部分为nginx中location 内部调用

以上代码保存到/home/software/openresty/nginx/lua/default.lua中。
openresty中nginx部分配置

location / {
	lua_code_cache on;
	content_by_lua_file /home/software/openresty/nginx/lua/default.lua;
}
location @php
{
	proxy_pass http://127.0.0.1:8888;
}

这段防CC代码比较适用于接口调用或者前后分离的站,因为一般都是通过接口访问,接口会带认证信息,这个认证信息可以做为判断唯一来源。
像普通网站没有比较适合判断唯一的地方,仅仅一个ip不能满足,而且ip可以通过代理更换,所以不适用于普通类型网站。

上面的配置参数表示:

以post请求中token字段做为redis中key唯一值,在60秒内请求次数超过10次后,则阻断120秒。待key超时后(120秒),则可以继续访问。

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/4447.html

作者:Venus

专注于 服务器运维与web架构 E-mail:venus#rootop.org

评论已关闭。