使用NGINX和Lua限制每个IP请求频率

我的目标是防止基于用户IP的高频请求,我在谷歌找到了openresty,发现它可以和Lua一起使用。所以我写了下面的脚本,我是一个Lua的新手,能否有人给我一些建议,甚至校正我。

这个脚本是用来阻止请求,如果请求超过100秒内请求超过3次

local limit_request_times = 3
local expire_time = 100

local user_ip = ngx.var.remote_addr

-- ngx.say("user_ip: ", user_ip)

local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end

local res, err = red:get(user_ip)
if res == ngx.null then
    ngx.say("no request record, add this user_ip to redis")
    ok, err = red:set(user_ip, 1)
    if not ok then
        -- ngx.say("add user_ip failed")
        ngx.exit(ngx.HTTP_FORBIDDEN)
        return
    else
        red:expire(user_ip, expire_time)
    end
else
    if tonumber(res) == limit_request_times then
        -- ngx.say("request reach max limit times")
        ngx.exit(403)
        return
    else
        ok, err = red:incr(user_ip)
        if not ok then
            ngx.say("failed to increment request times")
            return
        else
            ngx.say("increment request times: ", res + 1)
        end
    end
end
点赞
用户3177367
用户3177367

为什么不直接使用nginx内置的ngx_http_limit_req_module

例如:我们限制每个IP地址每分钟不超过2个请求。

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;

...

server {

    ...

    location /search/ {
        limit_req zone=one burst=3 nodelay;
    }
2015-07-31 07:20:06
用户1491378
用户1491378

你也可以通过 Lua 使用 resty.limit.conn 和/或 resty.limit.req 模块 https://nginx-extras.getpagespeed.com/lua/limit-traffic/

2022-03-01 07:45:14