[雑記] nginx の proxy_set_header の扱い

proxy_set_header の動きがちょっとおかしいなと思ったのでメモ。

  • バージョン
    • nginx 1.2.6

リバースプロキシを使う際、下記のような感じで、お決まりの proxy_set_header を http コンテキストで設定しておくと思います。

http {  
    proxy_redirect   off;
    proxy_set_header Host               $host;
    proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host   $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Real-IP          $remote_addr;

    upstream backend {
        server 127.0.0.1:8080;
    }

    server {
        listen       80 default_server;
        server_name  example.com;

        location / {
            proxy_pass http://backend;
        }
    }
}

このとき、バックエンドでリクエストヘッダを採取するとこんな感じ。

Host: example.com  
X-Forwarded-For: <SourceIP>  
X-Forwarded-Host: example.com  
X-Forwarded-Server: example.com  
X-Real-IP: <SourceIP>  
Connection: close  
User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
Accept: */*  

で、ある日、nginx とバックエンド間で KeepAlive ができると知って、下記のように設定を変更しました。

http {  
    proxy_redirect   off;
    proxy_set_header Host               $host;
    proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host   $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Real-IP          $remote_addr;

    upstream backend {
        server 127.0.0.1:8080;
        keepalive 16;               # <=== 追加
    }

    server {
        listen       80 default_server;
        server_name  example.com;

        location / {
            proxy_http_version 1.1;
            proxy_set_header Connection '';   # <=== 追加
            proxy_pass http://backend;        # <=== 追加
        }
    }
}

すると、リクエストヘッダが。。。

Host: backend  
User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
Accept: */*  

結局、下記のように設定したら解決しました。

server コンテキストにまとめたほうが見た目も良いですね。
virtual host によって proxy_set_header を変えたいこともあるでしょうし。

http {  
    upstream backend {
        server 127.0.0.1:8080;
        keepalive 16;
    }

    server {
        listen       80 default_server;
        server_name  example.com;

        proxy_redirect   off;
        proxy_set_header Host               $host;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host   $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header Connection         '';
        proxy_http_version 1.1;

        location / {
            proxy_pass http://backend;
        }
    }
}