web-dev-qa-db-ja.com

nginxtry_filesがhttpリダイレクトbeindロードバランサーを発行します。 httpsが必要

私のnginxインスタンスはSSLで終了するロードバランサーの背後にあり、すべてのURLがhttpsエンドポイントに到達するようにします。つまり、httphttpsにリダイレクトされます。

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番目のパラメーター)にヒットしたときに、httpstry_filesで直接リダイレクトするようにするにはどうすればよいですか。 $uri/<index>に一致するファイルを見つけます(ここで、indexは上記のnginx構成のindexディレクティブによって定義されます)?

hereherehere などの同様の質問を検索しましたが、リモートで関連するものは見つかりませんでした。

2
L. J.

@Florinが質問のコメントで指摘したように、try_filesは書き換えのみを実行します。だから私は戻ってtry_filesvhost.confブロックを省略しましたが、十分に真実でしたが、httpsnoでURLするのとまったく同じ動作に戻りました末尾のスラッシュは、対応するhttptrailedにリダイレクトされます。

解決

代わりに、私の質問のタイトルは「HTTPSからHTTPへのnginxリダイレクトを防ぐ方法」のようになっているはずです。これは AWSでnginxがHTTPSからHTTPにリダイレクトするのを防ぐ方法? という重複した質問になります。 @Richardは私の質問に対する彼のコメントで指摘し、彼はそれに答えました。

偶然にも、私の状況と質問は実際にはその質問のそれと同じです。 @Richardは、彼の回答の中で、nginxがリクエスターと同じ$schemeを想定している(つまりSSLで終了したロードバランサー)という問題を軽減する最善の方法は、httpを次のように置き換えることであると指摘しています。ロードバランサーのポイントのhttpsヘッダーにあるLocation。これは、私には不可能でした。次に、$schemehttpsになるリダイレクトを実行するときの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;
    }
}
1
L. J.