私のnginxインスタンスはSSLで終了するロードバランサーの背後にあり、すべてのURLがhttps
エンドポイントに到達するようにします。つまり、http
はhttps
にリダイレクトされます。
URLの末尾にスラッシュがある場合は、すべて問題ありません。それらはすべてうまくリダイレクトされます:
#!/bin/sh
do_curl() {
echo "\n$ do_curl $1"
curl -L -s -D - "$1" -o /dev/null | grep -iE 'Location|HTTP/|server'
}
$ do_curl https://example.com/
HTTP/2 200
$ do_curl http://example.com/foo/
HTTP/1.1 301 Moved Permanently
Location: https://example.com/foo/
HTTP/2 200
$ do_curl https://example.com/foo/
HTTP/2 200
ただし、同じURLに末尾のスラッシュがない場合、nginxのtry_files
は常にhttp
リダイレクトを発行しているようです: bad.png
これが私のnginxvhost.conf
です:
server {
listen 80;
root /app/;
index index.html index.htm;
# This 'if' block is only needed because my SSL-terminated Load balancer proxies both http and https to nginx.
# If my Load balancer only proxied https to nginx, and dropped http, this 'if' block can be omitted.
if ($http_x_forwarded_proto = "http") {
return 301 https://$Host$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
Nginxのtry_files
が$scheme
パラメーター(上記の$uri/
の2番目のパラメーター)にヒットしたときに、https
try_files
で直接リダイレクトするようにするにはどうすればよいですか。 $uri/<index>
に一致するファイルを見つけます(ここで、index
は上記のnginx構成のindex
ディレクティブによって定義されます)?
@Florinが質問のコメントで指摘したように、try_files
は書き換えのみを実行します。だから私は戻ってtry_files
のvhost.conf
ブロックを省略しましたが、十分に真実でしたが、https
がnoでURLするのとまったく同じ動作に戻りました末尾のスラッシュは、対応するhttp
trailedにリダイレクトされます。
代わりに、私の質問のタイトルは「HTTPSからHTTPへのnginxリダイレクトを防ぐ方法」のようになっているはずです。これは AWSでnginxがHTTPSからHTTPにリダイレクトするのを防ぐ方法? という重複した質問になります。 @Richardは私の質問に対する彼のコメントで指摘し、彼はそれに答えました。
偶然にも、私の状況と質問は実際にはその質問のそれと同じです。 @Richardは、彼の回答の中で、nginxがリクエスターと同じ$scheme
を想定している(つまりSSLで終了したロードバランサー)という問題を軽減する最善の方法は、http
を次のように置き換えることであると指摘しています。ロードバランサーのポイントのhttps
ヘッダーにあるLocation
。これは、私には不可能でした。次に、$scheme
がhttps
になるリダイレクトを実行するときの3つの方法について説明します。
3つの解決策のうち、私のために働いたのはabsolute_redirect off;
を使用することでした。これにより、nginxがリダイレクトで使用した間違った$scheme
を使用するのを防ぎました。
さて、私のvhost.conf
は次のようになります。
server {
listen 80;
root /app/;
index index.html index.htm;
absolute_redirect off;
# This 'if' block is only needed because my SSL-terminated Load balancer proxies both http and https to nginx.
# If my Load balancer only proxied https to nginx, and dropped http, this 'if' block can be omitted.
if ($http_x_forwarded_proto = "http") {
return 301 https://$Host$request_uri;
}
}