nginxではベースURLがhttpsに書き換えられる

nginxではベースURLがhttpsに書き換えられる

ベースドメインwww.domain.comのみを書き換えたいのですがhttps://www.domain.com デフォルトでは、https ブロックでは、~uri = "/" (ベース ドメイン) または静的コンテンツでない場合は、http:// にリダイレクトされます。

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

したがって、http ブロックでは、https にする必要がある場合は書き換えを行う必要があります。

server {
  listen              80;
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

http ブロックに $uri = '/' if ステートメントがない場合、直接アクセスすると https は正常に機能しますが、通常の http にアクセスするとリダイレクトされません (これは予想どおりです)。http ブロックにそのステートメントを入れると、数分以内にすべてが機能しなくなります。いくつかのリクエストでは機能するかもしれませんが、常に 1 分ほどで停止します。ブラウザーでは、すべてのリクエストに対して空白ページが表示されます。nginx を再起動しても、https ブロックと http ブロックの両方の if ステートメント ブロックを削除して nginx を再起動するまで、引き続き機能しません。エラー ログを見ると、何も記録されていません。アクセス ログを見ると、次のメッセージが表示されます。

"-" 400 0 "-" "-"

これは 400 エラーを意味していると思います。なぜこれが機能しないのか理解できません。私の最終目標は、ベース ドメインを https のみにして、他のすべてのページをデフォルトで http にすることです。どうすればこれを実現できますか?

答え1

最終的に、リダイレクト ループなしで引数を処理できるように、$uri を $request_uri に変更しました。

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($request_uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

次に、場所が = / の場合に即座に書き換えを行うようにhttpブロックを変更しました。

server {
  listen              80;
  location = / {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

他の書き換えを処理するための IF ステートメントがまだあり、その後、すべての特定の処理はそれらの下で実行されます。Christopher が提案したとおり、または私が最初に質問で提示した方法ですべてを処理しようとすると、リダイレクト ループとエラーが発生するのは、おそらく私の特定の構成によるものです。

答え2

すべての if ステートメントは必要ありません。location ステートメントを使用する必要があります。

server {
    listen              80;
    #rewrite base (/) to ssl
    location = / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }

    #serve anything else
    location / {
        [serve non-ssl page ...]
    }
}

server {
    listen              443;

    #serve base url
    location = / {
        [serve ssl page ...]
    }

    #serve assets
    location ~ ^/(img|js|css|static)/ {
        [serve ssl assets ...]
    }

    #rewrite anything else
    location / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }
}

これはテストされていないためエラーが発生する可能性がありますが、動作するはずです

関連情報