web-dev-qa-db-ja.com

https使用時のホストに基づくnginxプロキシ

NginxをSSLプロキシとして使用する必要があります。これは、サブドメインに応じて異なるバックエンドにトラフィックを転送します。

複数の「サーバー{」セクションを定義する必要があるように思えますが、SSLでは正しく機能しません。これを行うと、httpsトラフィックを処理するまでサーバー名が不明であるため、最初の仮想ホストで常にSSLが処理されます。

シナリオ:

  • 1つのIPアドレス
  • 1つのSSLワイルドカードワイルドカード
  • 次のようにアクセスする必要がある複数のバックエンド:

    https://one.mysite.com/ -> http://localhost:8080
    https://two.mysite.com/ -> http://localhost:8090
    

Nginxは「if」が悪であると言います: http://wiki.nginx.org/IfIsEvil ですが、他に何ができますか?

私はこれを試しましたが、うまくいきません。500エラーが表示されますが、エラーログには何も記録されません。

    server {
    listen 443;
    server_name *.mysite.com;

    ssl on;
    ssl_certificate ssl/mysite.com.crt;
    ssl_certificate_key ssl/mysite.com.key;

    location / {
        if ($server_name ~ "one.mysite.com") {
            proxy_pass http://localhost:8080;
        }
        if ($server_name ~ "two.mysite.com") {
            proxy_pass http://localhost:8090;
        }
    }

誰かがNginxでこれを何とかして達成しましたか?任意のヘルプ/代替、リンク、いただければ幸いです。

16

私は基本的に「サーバー」ブロックの外でSSLオプションとSSL証明書を定義するソリューションを見つけました:

ssl_certificate ssl/mysite.com.crt;
ssl_certificate_key ssl/mysite.com.key;
ssl_session_timeout  5m;
ssl_protocols        SSLv3 TLSv1;
ssl_ciphers          ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+EXP;
ssl_prefer_server_ciphers   on;

server {
    listen 80;
    server_name *.mysite.com;
    rewrite ^ https://$Host$request_uri? permanent;
}
server {
    listen 443 ssl;
    server_name one.mysite.com;

    ssl on;

    location / {
        proxy_pass http://localhost:8080;
    }
}
server {
    listen 443 ssl;
    server_name two.mysite.com;

    ssl on;

    location / {
        proxy_pass http://localhost:8090;
    }
}

重要なこと:

  • 「ssl on;」 httpsでリッスンする「サーバー」ブロック内にある必要がある唯一のものは、外部に置くこともできますが、ポート80でリッスンする「サーバー」ブロックが予想されるhttpではなく、httpsプロトコルを使用するようにするものです。
  • 「ssl_certificate」、「ssl_ciphers :、およびその他の「ssl_ *」は「server」ブロックの外にあるため、nginxはserver_nameなしでSSLオフロードを実行します。これは、ホスト名に基づいてSSL復号化を実行できないためです。 、この段階ではURLは暗号化されています。
  • Javaとcurlが動作するようになりました。 server_nameがありません-ホストが一致しません。
27

短い答えは Server Name Indication を使用することです。これは一般的なブラウザとcURLでデフォルトで機能するはずです。

4
Melvyn

http://www.informit.com/articles/article.aspx?p=1994795 によると、実際には2つの「サーバー」セクションがあり、2つの異なるサーバー名が必要です。それぞれに、ssl_ *ディレクティブを含める必要があります。

1
Pixou