log_by_lua_block {
local status = ngx.status
if status ~= 404 then
return -- 只統計 404
end
local ip = ngx.var.remote_addr
local count_dict = ngx.shared.ip_404_count
local blacklist = ngx.shared.ip_blacklist
-- 統計時間窗口(例如 60 秒)
local window = 60
local threshold = 10 -- 60 秒內 10 次 404 則封禁
local ban_time = 600 -- 封禁 600 秒
-- 原子增加計數,并設置過期時間
local new_count, err = count_dict:incr(ip, 1, 0, window)
if not new_count then
ngx.log(ngx.ERR, "failed to incr 404 count: ", err)
return
end
-- 如果達到閾值,加入黑名單
if new_count >= threshold then
local ok, err = blacklist:set(ip, true, ban_time)
if not ok then
ngx.log(ngx.ERR, "failed to set blacklist: ", err)
else
-- 可選:刪除計數器,避免重復封禁
count_dict:delete(ip)
end
end}