当ignore_invalid_headers设置为off时,Nginx会丢弃无效的标头

时间:2016-02-04 05:50:19

标签: nginx

这是我的nginx conf:

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,所有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没有理由抛弃这些标题。

有谁知道如何修复它? 提前谢谢。

2 个答案:

答案 0 :(得分:5)

我遇到了同样的问题。

你可以进行有趣的测试。 在主机标头之前发送一些无效标头的请求以及之后的一些无效标头。

您会发现您可以在Host标头之后收到无效的标头,以及Host标头丢失之前的标题。

此问题的解决方案是在http级别将ignore_invalid_headers设置为off。

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

因此,您需要告诉Nginx不要在主机标头之前使用 http级别中 ignore_invalid_headers off 指令丢弃无效标头。 < / p>

答案 1 :(得分:0)

添加

underscores_in_headers on;

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