94 lines
2.4 KiB
Lua
94 lines
2.4 KiB
Lua
-- User-Agent限制模块
|
||
-- 功能:根据User-Agent进行访问控制(黑白名单)
|
||
|
||
local _M = {}
|
||
|
||
local common_config = require "config.common_config"
|
||
local logger = require "lib.logger"
|
||
|
||
-- 获取配置
|
||
local function get_config()
|
||
return common_config.ua_limit
|
||
end
|
||
|
||
-- 检查User-Agent是否在列表中(支持部分匹配)
|
||
local function ua_in_list(ua, list)
|
||
if not ua or #list == 0 then
|
||
return false
|
||
end
|
||
|
||
for _, pattern in ipairs(list) do
|
||
-- 使用字符串查找,支持部分匹配
|
||
if ua:find(pattern, 1, true) then
|
||
return true
|
||
end
|
||
end
|
||
|
||
return false
|
||
end
|
||
|
||
-- 主函数:检查User-Agent
|
||
-- 返回值:
|
||
-- - true: 允许访问
|
||
-- - false: 拒绝访问
|
||
function _M.check_ua_limit()
|
||
local cfg = get_config()
|
||
|
||
-- 如果未启用,直接放行
|
||
if not cfg.enabled then
|
||
return true
|
||
end
|
||
|
||
-- 获取User-Agent
|
||
local ua = ngx.var.http_user_agent
|
||
|
||
-- 如果没有UA,记录日志但不阻止(可根据需求调整)
|
||
if not ua or ua == "" then
|
||
logger.log_info("Empty User-Agent", {
|
||
ip = ngx.var.remote_addr,
|
||
uri = ngx.var.request_uri
|
||
})
|
||
return true
|
||
end
|
||
|
||
-- 检查白名单:在白名单中的UA总是放行
|
||
if ua_in_list(ua, cfg.whitelist) then
|
||
logger.log_info("User-Agent whitelisted", {
|
||
ua = ua,
|
||
action = "ALLOWED"
|
||
})
|
||
return true
|
||
end
|
||
|
||
-- 检查黑名单:在黑名单中的UA会被阻止
|
||
if ua_in_list(ua, cfg.blacklist) then
|
||
logger.log_warn("User-Agent blocked", {
|
||
ua = ua,
|
||
action = cfg.action,
|
||
status = tostring(cfg.status_code)
|
||
})
|
||
|
||
-- 执行处置策略
|
||
if cfg.action == "allow" then
|
||
-- 仅记录日志,不阻止
|
||
return true
|
||
elseif cfg.action == "rate_limit" then
|
||
ngx.status = cfg.status_code or 429
|
||
ngx.header["Content-Type"] = "text/plain; charset=utf-8"
|
||
ngx.say(cfg.message or "Rate limit exceeded")
|
||
return false
|
||
else
|
||
-- 默认封禁
|
||
ngx.status = cfg.status_code or 403
|
||
ngx.header["Content-Type"] = "text/plain; charset=utf-8"
|
||
ngx.say(cfg.message or "Access denied")
|
||
return false
|
||
end
|
||
end
|
||
|
||
-- 不在任何列表中,正常放行
|
||
return true
|
||
end
|
||
|
||
return _M
|