Nginx 在 ignore_invalid_headers 设置为 off 时丢弃无效的 headers
问题:Nginx 在 ignore_invalid_headers 设置为 off 时丢弃无效的 headers
这是我的 nginx 配置文件:
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server_names_hash_max_size 10000;
server_names_hash_bucket_size 128;
client_max_body_size 2m;
server {
listen 80;
server_name testheader.com;
ignore_invalid_headers off;
proxy_http_version 1.1;
location ~* ^/testheader {
proxy_request_buffering off;
proxy_next_upstream off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection "";
proxy_read_timeout 180s;
set $upstream 127.0.0.1:8888;
proxy_pass http://$upstream ;
}
}
}
我发送了一个示例请求如下
POST /testhead/magic?null HTTP/1.1:
content-type: text/plain; charset=UTF-8
test_trace_id: 1234567890123456
test_span_id: 1234567890123456
x-forwarded-for: 127.0.0.1:8080
x-test-client-host: 127.0.0.1:8888
x-test-request.toplevel.uuid: xxxxxxx-xxxxxx-xxxxxx-xxxxxxx
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip
connection: keep-alive
accept-language: null
host: top.ctrip.uat.qa.nt.ctripcorp.com
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Content-Length: 264
{"ActCode":2}
我希望从我的上游服务器 127.0.0.1:8888 中获取所有无效的标头,例如 test_trace_id、test_span_id、all x-{$value},但 ** 没有一个标头是显示**。同时,nginx 日志在发送无效标头阶段没有报告任何错误。
我还尝试使用 tcpdump 在目标上游服务器上捕获请求,我确信 nginx 甚至没有尝试将它们发送出去。
但是,在另一个示例中:
POST /testhead/magic?null HTTP/1.1:
content-type: text/plain; charset=UTF-8
test_trace_id: 1234567890123456
test_span_id: 1234567890123456
host: top.ctrip.uat.qa.nt.ctripcorp.com
x-forwarded-for: 127.0.0.1:8080
x-test-request.toplevel.uuid: xxxxxxx-xxxxxx-xxxxxx-xxxxxxx
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip
connection: keep-alive
accept-language: null
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Content-Length: 264
{"ActCode":3}
无效的标头 x-test-request.toplevel.uuid 被发送到上游服务器。
我不认为第二个示例中缺少的两个标题是问题的原因。我尝试了很多请求,似乎这个问题是随机发生的,有时该指令可以完美运行,有时则不能。
它是一个错误吗?配置文件清楚地告诉 nginx 忽略无效的标头并将它从客户端获得的任何内容传递到上游。 Nginx 没有理由丢弃这些标头。
有谁知道如何修理它?提前致谢。
解答
我遇到了同样的问题。
你可以做一个有趣的测试。发送一个请求,其中在 Host 标头之前有一些无效的标头,在它之后有一些无效的标头。
你会发现在Host头之后会收到无效的头,而在Host头之前的会丢失。
这个问题的解决方法是在http级别设置ignore_invalid_headers为off。
关于问题的原因。我认为 Nginx 需要在进入服务器范围之前读取 Host 标头,因为域,也就是服务器名称,存储在 Host 标头中。并且 Nginx 在此阶段会丢弃 Host 标头 之前的所有无效标头,因为服务器范围内的指令 ignore_invalid_headers off 在此阶段不起作用。所有其他标头都将在服务器范围内读取,因此可以读取 Host header 之后的无效标头,因为服务器范围内的指令 ignore_invalid_headers off 告诉 Nginx 忽略无效标头。
所以你需要告诉 Nginx 不要在 http 级别使用指令 ignore_invalid_headers off 丢弃 Host 标头之前的无效标头。
更多推荐

所有评论(0)