Http-Guard 是第三方 Nginx 模块,可拦截非法请求头(如恶意 User-Agent、Referer、Host 等),但仅限请求头匹配,不处理 body 或 URL 参数;需显式启用 guard on;,规则须带 $http_ 前缀,支持 403/444/503 响应码,拦截发生在日志记录前,故 access.log 无记录。

Http-Guard 是什么,它真能拦住恶意请求头?
Http-Guard 不是 Nginx 官方模块,也不是 OpenResty 内置组件,而是一个第三方 ngx_http_guard_module,需手动编译进 Nginx。它不能替代 WAF,但对特定攻击面(如非法 User-Agent、Referer、Host、自定义头)有轻量级拦截能力。关键判断:如果你的流量已过云 WAF 或有 Lua 能力,优先用 access_by_lua_block;如果只有原生 Nginx 且不想引入 OpenResty,Http-Guard 才值得考虑。
编译安装时最常卡在哪儿?
官方仓库(如 https://github.com/loveshell/ngx_http_guard_module)提供的代码不兼容 Nginx 1.21+,主因是 ngx_http_upstream_t 结构体字段变更。常见失败现象:error: 'ngx_http_upstream_t' has no member named 'resolved'。
- 确认 Nginx 版本:运行
nginx -v,若 ≥1.21,必须打补丁或降级到 1.20.x - 下载对应分支:比如 Nginx 1.18 → 用
nginx-1.18分支源码,别直接 clone main - configure 时加
--add-module=/path/to/ngx_http_guard_module,**不要**加--with-http_ssl_module以外的无关模块,避免符号冲突 - 编译后验证:
nginx -V 2>&1 | grep -o guard应输出guard
怎么配置才能真正生效?
Http-Guard 的规则靠 guard_rule 指令写在 http、server 或 location 块里,但它**只检查请求头,不处理 body 或 URL 参数**。典型误配:把 guard_rule $http_user_agent "sqlmap|nmap" 403; 放在 http 块却忘了开启 guard on;。
-
guard on;必须显式启用,否则所有guard_rule都被忽略 - 匹配目标必须带
$http_前缀,如$http_referer、$http_x_forwarded_for;不支持$arg_或$request_uri - 正则模式默认区分大小写,要忽略大小写得写成
guard_rule $http_user_agent "(?i)curl.*python" 403; - 状态码只能是 403 / 444 / 503,其中
444表示断连不发响应,适合暴力扫描封禁
示例(放在 server 块内):
guard on; guard_rule $http_user_agent "sqlmap|nikto|dirbuster" 444; guard_rule $http_host "^www\.[^\.]+\.(com|org)$" 403;
为什么日志里看不到被拦的请求?
Http-Guard 拦截发生在 Nginx 请求处理早期(rewrite 阶段前),此时 access log 尚未记录。你只会看到客户端超时或空响应,但 access.log 里没有对应条目 —— 这不是配置错误,是模块设计如此。
- 排查是否生效:用
curl -H "User-Agent: sqlmap/1.0" http://your.site/,看返回是否为 444 或连接重置 - 开启 debug 日志(
error_log /var/log/nginx/error.log debug;),搜索guard关键字,能看到匹配过程 - 注意性能影响:每条
guard_rule都触发一次 PCRE 编译(若含正则),规则过多会拖慢 worker 进程,建议合并为单条复杂正则,而非堆砌多条简单规则
真正难搞的是混合头攻击:比如合法 User-Agent + 恶意 X-Forwarded-For + 异常 Accept-Encoding,Http-Guard 不支持跨头逻辑组合(如 “A 且 B” 或 “A 或 C”),这种场景必须换 Lua 或专用 WAF。


















