ここに私の短縮された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バージョンを分離できるように、冗長構成情報を除外する(外部ファイルを含める以外に)他の方法はありますか?
さて、私は少しインスピレーションを得て試しました:
proxy_redirect http:// $scheme://;
トリックを行うようです。ただし、これはまだ私にはハッキリしているように見えるので、同じ結果を達成するために私が間違っていることやハックが少ない方法についてのガイダンスを歓迎します。
他の解決策は、要求がHTTPまたはHTTPSのどちらであるかをアップストリームに示し、それに応じたリダイレクトを発行させることです。これをnginx設定に追加すると、アップストリームが検査するヘッダーが設定されます。
proxy_set_header X-Scheme $scheme;