ifを使用せずに、Amazon ELBの背後にあるすべてのhttpリクエストをhttpsにリダイレクトします


27

現在、http://www.example.orghttps://www.example.orgの両方にサービスを提供しているELBがあります

http://www.example.orgを指すリクエストがhttps://www.example.orgにリダイレクトされるように設定したいと思います

ELBはhttps要求をhttp要求として送信するため、次を使用します。

server {
      listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
}

https://www.example.orgへのリクエストはnginxのポート80 に対して行われるため、機能しません。

私はそれを次のように書き換えることができることを知っています

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$1 permanent;
      }
}

しかし、私が読んだifすべてのことは、nginx構成内のすべてのコストで回避されるべきであると述べており、これはすべてのリクエストに当てはまります。また、ヘルスチェック用に特別な個別の構成を設定する必要があることを意味します(ここで説明するように、「…ELBがHTTPSエンドポイントとして機能し、HTTPトラフィックのみをサーバーに送信するELBの背後にいる場合、 ELBが必要とするヘルスチェックに対してHTTP 200 OK応答で応答する機能を破壊します」)。

ログインをnginx設定ではなくWebアプリケーションのコードに入れることを検討しています(そしてこの質問の目的のためにDjangoベースのアプリケーションであると仮定しましょう)が、それがオーバーヘッドよりも大きいかどうかはわかりませんif で構成。


こんにちは、これらのコードをどこに置くか教えてください。
ユアン少林寺Maculelêライ

@YuAnShaolinMaculelêLai確かに。これらはnginxの設定ファイルなので、コードは/etc/nginx/conf.d/のファイルに配置するだけです。通常、「domainname」が問題のWebサイトのドメインであるファイルにdomainname.confという名前を付けます。.confで終わる限り、ファイルに任意の名前を付けることができます。
ジョーダンライター

どうもありがとうございました。.confに続く新しいファイルを作成しようとしました。しかし、私にはうまくいきませんでした。次に、AWSから生成された/etc/nginx/conf.d/のファイルにコードを配置します。今は動作します。
元安少林Maculelêライ

回答:


9

それがそのように正しく動作している場合、それを怖がらないでください。http://wiki.nginx.org/IfIsEvil

ifの動作に一貫性がないことに注意することが重要です。2つの同一のリクエストがあると、一方でランダムに失敗し、他方で動作し、適切なテストとifの使用が可能です。ただし、利用可能な他のディレクティブを使用するというアドバイスは、まだ非常に当てはまります。


このページには、「ロケーションコンテキストで使用した場合に問題がある」とも記載されています。の代わりにlocation {}、あなたがする必要があることを行うことができるように思えますserver {}。(ただし、これが正しくない場合はお知らせください!)
エクスカリバー

15
  1. AWS ELBマッピングELB:80をインスタンス:80に、ELB:443をインスタンス:1443に設定します。
  2. nginxをバインドして、ポート80および1443でリッスンします。
  3. ポート80に到着した要求をポート443に転送します。
  4. ヘルスチェックはHTTP:1443である必要があります。301リダイレクトのため、HTTP:80を拒否します。

AWS elbセットアップ

NGINXセットアップ

    server {
       listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
    }

    server {
       listen         1443;
       server_name    www.example.org;
   } 

ヘルスチェックの設定はどうですか?それについて詳しく説明してください。
samkhan13

これは、ヘルスチェックをhttp:80に設定すると機能しませんでした。ヘルスチェックは失敗します。
samkhan13

2
ヘルスチェックが必要ですHTTP:1443HTTP:80301リダイレクトのため、拒否します。
cbron

これはほとんど私にとってはうまくいきましたが、書き換え行は私のワイルドカードドメインでは機能しませんでした。この別の投稿はその部分を修正しました:serverfault.com/questions/447258/…–
Ron

9

このソリューションは条件付きロジックを使用しますが、受け入れられた答えが示唆するように、これも大丈夫だと思います。参照:https : //stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

また、これには、イメージのawsセキュリティ設定で追加のポートを開く必要はありません。AWS LBでsslを終了し、httpsトラフィックをインスタンスのhttpポート80にルーティングできます。

この例では、LBヘルスチェックがポート80で/ healthにヒットし、これがアプリサーバーにルーティングされるため、ヘルスチェックはnginxとアプリの両方が動作していることを検証します。

server {
  listen 80 default deferred;

  set $redirect_to_https 0;
  if ($http_x_forwarded_proto != 'https') {
    set $redirect_to_https 1;
  }
  if ($request_uri = '/health') {
    set $redirect_to_https 0;
  }
  if ($redirect_to_https = 1) {
    rewrite ^ https://www.example.com$request_uri? permanent;
  }
  ...
}

1
これを行うにはよりエレガントな方法がなければならない
エドワード・

0

これで、HTTPポート80をHTTPSポート443にリダイレクトするAWSロードバランサー設定で新しいリスナーを作成できるようになりました。したがって、nginx / apacheの設定に触れる必要はありません。


残念ながら、それはまだCloudformationではサポートされていません
Aryeh Leib Taurog
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.