web-dev-qa-db-ja.com

nginxがリバースプロキシとして使用されている場合にトラフィックをhttpsからhttpにリダイレクトしないようにする

ここに私の短縮されたnginx vhost confがあります:

upstream gunicorn {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com ~^.+\.domain\.com$;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_Host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 120;
        proxy_pass http://gunicorn;
    }
}

同じサーバーがHTTPとHTTPSの両方を処理する必要がありますが、アップストリームがリダイレクトを発行すると(たとえば、フォームが処理された後)、すべてのHTTPS要求がHTTPにリダイレクトされます。この問題を修正する唯一の方法は、proxy_redirectを次のように変更することです。

proxy_redirect http:// https://;

これはHTTPSからのリクエストに対してはうまく機能しますが、リダイレクトがHTTP経由で発行された場合、それをHTTPSにリダイレクトすることも問題です。

必死で、私は試しました:

if ($scheme = 'https') {
    proxy_redirect http:// https://;
}

しかし、nginxはproxy_redirectがここでは許可されていないと不平を言っています。

私が考えることができる他の唯一のオプションは、2つのサーバーを個別に定義し、SSLサーバーのみにproxy_redirectを設定することですが、その後、残りのconfを複製します(省略したserverディレクティブにはたくさんあります)簡単にするため)。 includeディレクティブを使用して冗長性を取り除くこともできることはわかっていますが、本当に依存関係のないconfファイルを1つだけ保持したいのです。

それで、最初に、問題を完全に無効にする欠けているものはありますか?または、次に、そうでない場合、サーバー構成のHTTPバージョンとHTTPSバージョンを分離できるように、冗長構成情報を除外する(外部ファイルを含める以外に)他の方法はありますか?

16
Chris Pratt

さて、私は少しインスピレーションを得て試しました:

proxy_redirect http:// $scheme://;

トリックを行うようです。ただし、これはまだ私にはハッキリしているように見えるので、同じ結果を達成するために私が間違っていることやハックが少ない方法についてのガイダンスを歓迎します。

29
Chris Pratt

他の解決策は、要求がHTTPまたはHTTPSのどちらであるかをアップストリームに示し、それに応じたリダイレクトを発行させることです。これをnginx設定に追加すると、アップストリームが検査するヘッダーが設定されます。

proxy_set_header    X-Scheme $scheme;
5
mgorven