nginx 的 ngx_http_browser_module 仅识别旧版浏览器并设置 $ancient_browser 变量,拦截需配合 if + return/rewrite 实现;其通过不区分大小写的子串匹配判断 ua,支持显式配置 curl、wget 等工具 ua,并须在 server 或 location 块中使用 if 触发响应动作,避免嵌套及 proxy_pass 等禁用操作。

Nginx 的 ngx_http_browser_module 本身不提供“拦截”功能,它只负责根据 User-Agent 字符串识别浏览器类型并设置变量(如 $ancient_browser)。真正实现拦截,需要配合 if + return 或 rewrite 等指令完成。配置核心在于精准定义“旧版浏览器”的识别规则,并在合适作用域中触发响应动作。
明确 ancient_browser 的匹配逻辑
该模块通过子串匹配判断是否为旧版浏览器,不是正则匹配,也不区分大小写:
-
ancient_browser Links Lynx netscape4;表示只要User-Agent包含Links、Lynx或以Mozilla/[1-4]开头(netscape4是特殊关键字)就视为旧版 - 若请求头中根本没有
User-Agent,Nginx 默认将其当作“未列出”,此时是否算旧版取决于是否配置了modern_browser unlisted - 推荐显式覆盖所有低风险 UA:加上
ancient_browser curl wget httpie python-urllib;可捕获大量自动化工具请求
在 server 或 location 中启用拦截动作
识别出变量后,必须用条件语句触发实际行为。注意:if 只能在 server 或 location 块中使用,且不能嵌套:
- 直接返回提示页:
if ($ancient_browser) { rewrite ^ /unsupported.html break; } - 返回 403 拒绝访问:
if ($ancient_browser) { return 403; } - 重定向到升级引导页:
if ($ancient_browser) { return 302 https://example.com/upgrade; } - 搭配日志标记便于审计:
log_format ancient '$remote_addr - $ancient_browser "$request"';
避免常见配置陷阱
Browser 模块的行为依赖于 UA 解析时机和变量生效范围,容易因位置错误失效:
-
modern_browser和ancient_browser指令必须放在http、server或location块内,不能写在upstream或map中 -
$ancient_browser变量仅在匹配成功时才被设为非空值(默认是1),所以if ($ancient_browser = "1")写法冗余,直接if ($ancient_browser)即可 - 不要在
if中调用proxy_pass—— Nginx 官方明确禁止,会导致不可预期行为 - 若需全局生效,把
ancient_browser和if都放在http块的server内;若只针对某路径,在对应location中配置更安全
补充建议:结合 Host 头与协议特征增强识别
单纯依赖 UA 容易被伪造,建议组合其他低开销特征提升准确性:
- 对无
Host头的请求(常见于 HTTP/1.0 扫描器)统一拦截:if ($host = "") { return 444; } - 限制 HTTP 方法,屏蔽非常规请求:
limit_except GET HEAD { deny all; } - 开启
log_not_found off;减少因 UA 识别失败产生的干扰日志











