ignore_invalid_headers不能真正过滤非法请求头,仅控制nginx对非法header名(如下划线、空格、控制字符)的处理方式:on时丢弃该头但放行请求,off时立即返回400错误;必须在http或server块中配置,不校验header值、不拦截请求、非安全机制。

ignore_invalid_headers 不能真正“过滤”非法请求头,它只控制 Nginx 遇到非法请求头时的处理方式:是跳过该头继续处理请求,还是直接拒绝请求并返回 400 错误。它的作用范围仅限于请求头名称的格式合规性检查(如是否含下划线 _、空格、控制字符、非 ASCII 字符等),不涉及请求体、URL 或 header 值内容。
它实际怎么工作
-
设为
on(默认):Nginx 发现非法 header 名(例如X-User_Id、X%20Cookie、Host: example.com\r\nX-Foo:)时,直接丢弃该字段,不传给后端、不映射为$http_x_user_id等变量,但请求本身照常进入 location 匹配和 upstream 转发。 -
设为
off:只要检测到任意一个非法 header 名,Nginx 立即返回400 Bad Request,且不执行任何后续逻辑——不会匹配 location,不会调用 proxy_pass,也不会记录 access_log(除非 error_log 记录了)。
⚠️ 注意:这个指令只校验 header 名称格式,不校验值;也不拦截请求本身,更不是安全防护手段。
正确配置位置与写法
必须在 http{} 或 server{} 块中设置,不能写在 location{} 内,否则启动会报错:
http {
ignore_invalid_headers off; # 全局生效:所有 server 都严格校验
server {
listen 80;
server_name example.com;
# 此处无需重复写,继承 http 块设置
}
}
错误示例(语法错误):
location / {
ignore_invalid_headers off; # ❌ 不允许
}
常见触发非法 header 的情况
- 客户端 SDK 或测试工具使用下划线命名自定义头,如
X-API_Key、X_User_ID - 前端 fetch 设置了含空格或 Unicode 符号的 header 名(如
X-Test Header) - 恶意扫描器发送含
\r、\n、\x00等控制字符的 header - 上游 CDN/WAF 透传未清洗的畸形 header(如
Host: a.com\r\nX-Bad:)
这些都会被 Nginx 判定为“非法”,触发 ignore_invalid_headers 行为。
它不是安全机制,别指望靠它防攻击
- 请求即使含
X-Forwarded-For: <script></script>或Referer: javascript:alert(1),只要 header 名合规,ignore_invalid_headers完全无感; - CRLF 注入、超长 header、编码混淆、header 值注入等,它一律不管;
- 下划线限制主要源于 CGI 兼容性(防止
HTTP_PROXY变量污染),不是为安全设计。
真正需要拦截非法 header,应组合以下方式:
- 用
map+if对 header 名做正则校验,匹配即return 400 - 开启
underscores_in_headers on(仅当业务强依赖且信任客户端时) - 配合 WAF(如 ModSecurity)或 OpenResty 做深度解析与规则匹配
- 启用
error_log info查看日志中类似client sent invalid header line: "X-Bad_Header: value"的记录,定位问题源头
生产环境配置建议
- 大多数场景保持默认
ignore_invalid_headers on,避免因个别客户端乱传 header 导致大量合法请求被 400 中断; - 若为高安全要求系统(如金融类 API 网关),可设为
off,同时配合日志监控、告警和上游客户端治理; - 搭配
large_client_header_buffers和client_header_buffer_size控制 header 总长度,防 DoS 类攻击; - 所有敏感 header(如
Host、Origin、Referer)应单独用if或map白名单校验,不依赖ignore_invalid_headers。











