【问题标题】:Nginx discards invalid headers when ignore_invalid_headers is set to off当 ignore_invalid_headers 设置为 off 时,Nginx 会丢弃无效的标头
【发布时间】:2017-05-09 15:04:56
【问题描述】:

这是我的 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 日志在发送无效 headers 阶段没有报告任何错误。

我还尝试使用 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 没有理由丢弃这些标头。

有人知道怎么解决吗? 提前致谢。

【问题讨论】:

  • 您阅读过文档吗? If the directive is specified on the server level, its value is only used if a server is a default one. The value specified also applies to all virtual servers listening on the same address and port. 你的服务器不是默认的,所以这个指令被忽略了。
  • 顺便说一句,也许你需要underscores_in_headers
  • @AlexeyTen 感谢您的快速回复,并对我不完整的问题描述感到抱歉。将指令放入默认服务器可能是解决它的一种方法,让我们看看。但是,在某些情况下,testheader.com 服务器下的指令确实有效。我更新了描述,以便可以更清楚地描述问题。我仍在寻求解释为什么这个问题是随机提出的。如果你知道为什么会这样,你会很高兴解释原因。再次感谢您的建议。 :)
  • x-forwarded-for 是完全有效的标头。
  • @AlexeyTen 感谢您的回答。 :) 它有帮助。

标签: nginx


【解决方案1】:

我也遇到了同样的问题。

您可以进行有趣的测试。 发送在 Host 标头之前带有一些无效标头,在其之后带有一些无效标头的请求。

你会发现在Host头之后会收到无效的头,而在Host头之前的会丢失。

解决这个问题的方法是在http级别设置ignore_invalid_headers为off。

关于问题的原因。我认为 Nginx 需要在进入服务器范围之前读取 Host 标头,因为域,也就是服务器名称,存储在 Host 标头中。并且 Nginx 在此阶段丢弃 Host header 之前的所有无效标头,因为服务器范围内的指令 ignore_invalid_headers off 在此阶段不起作用。所有其他头文件都将在服务器范围内读取,因此可以读取 Host header 之后的无效头,因为服务器范围内的指令 ignore_invalid_headers off 告诉 Nginx 忽略无效头.

所以你需要在 http 级别使用指令 ignore_invalid_headers off 告诉 Nginx 不要丢弃 Host header 之前的无效标头。

【讨论】:

  • because the directive **ignore_invalid_headers off** in server scope tells Nginx to ignore the invalid headers. 那不是告诉 nginx 不要忽略无效的标头吗? “true”的值会告诉 nginx“是的,忽略无效的标头”。 “false”值告诉 nginx“不,不要忽略无效的标头”。
【解决方案2】:

添加

underscores_in_headers on;

ignore_invalid_headers 关闭时,通常会允许更多的无效标头通过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    相关资源
    最近更新 更多