Nginx proxy_set_header 配置注意事项

转载自:https://www.jianshu.com/p/fd16b3d10752

如果没有特别注意 proxy_set_header 配置,使用 proxy_set_header 可能会引起以下问题:

  1. 丢失需要的 header 信息
  2. 拿到意外的 Host 信息
  3. upstream 中的 keepalive 不能生效

在server{}字段,要么,设置齐全关于常用的proxy_set_header, 要么,

要么就在server{}字段一个都不设置,但是在server{}字段的上级要设置齐全。

有点绕

如果在server{}字段设置了任何的proxy_set_header, 那么上级的proxy_set_header都不会继承,只使用server{}字段上默认和新设置的的而已

server{}字段,系统有两个默认

分别是

proxy_set_header Host $proxy_host;

proxy_set_header Connection close;

官方文档

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

Allows redefining or appending fields to the request header passed to the proxied server. 
The value can contain text, variables, and their combinations.
These directives are inherited from the previous level
if and
only if there are no proxy_set_header directives defined on the current level.
By default, only two fields are redefined: proxy_set_header Host $proxy_host; proxy_set_header Connection close; 允许重新定义或附加字段到传递给代理服务器的请求头。该值可以包含文本、变量及其组合。
当且仅当当前级别上没有定义 proxy_set_header 指令时,这些指令从上级继承。默认情况下,只有两个值被重新定义:

问题的关键

在当前级别的配置中没有定义 proxy_set_header 指令时,这些指令从上级继承。
如果当前级别的配置中已经定义了 proxy_set_header 指令,在上级中定义的 proxy_set_header 指令在当前级别都会失效

举个例子:

这个配置,如果用户访问 example.com/test/index.html,后端服务拿到的 Host 值是 example.com_test,
而不是期望的 example.com;后端服务器会收到 Connection: close 的 Header,
而不能复用连接;后端服务器也不能从 Header 中获取到 X-Real-IP。
http {
    ...
    proxy_http_version 1.1;
    proxy_set_header Host       $host;
    proxy_set_header Connection "";
    proxy_set_header X-Real-IP $remote_addr;

    upstream example.com_test {
        server 127.0.0.1:8080;

        keepalive 16;
    }

    server {
        server_name  example.com;

        location ^~ /test/ {
            proxy_set_header test      test;
            proxy_pass http://example.com_test;
        }
    }
}

注意: 在 location ^~ /test/ {...} 中真正生效的 proxy_set_header 只有这三个

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;
proxy_set_header test      test;

正确的配置

http {
    ...
    proxy_http_version 1.1;
    proxy_set_header Host       $host;
    proxy_set_header Connection "";
    proxy_set_header X-Real-IP $remote_addr;

    upstream example.com_test {
        server 127.0.0.1:8080;

        keepalive 16;
    }

    server {
        server_name  example.com;

        location ^~ /test/ {
            proxy_set_header test      test;
            proxy_set_header Host       $host;
            proxy_set_header Connection "";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://example.com_test;
        }
    }
}
原文地址:https://www.cnblogs.com/faberbeta/p/nginx009.html