-- 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