web-dev-qa-db-ja.com

nginxでSSLに強制またはリダイレクトする方法は?

次のようなサブドメインにサインアップページがあります:https://signup.example.com

HTTPS経由でしかアクセスできないはずですが、HTTP経由でアクセスして404を取得する可能性があるのではないかと心配しています。

Nginxのhtml/serverブロックは次のようになります。

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/Rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

http://signup.example.comにアクセスしたユーザーがhttps://signup.example.comにリダイレクトされるように、何を追加できますか? (FYI私はRails SSLを強制できるプラグインがあることを知っていますが、それを回避することを望んでいました)

223
Callmeed

nginx pitfalls によると、代わりに$request_uriを使用して、不要なキャプチャを省略した方が少し良いです。その場合、nginxがクエリ引数を2倍にしないように疑問符を追加します。

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}
144
Pratik Amin

公式のハウツー で説明されている最善の方法は、 return ディレクティブを使用することです。

server {
    listen      80;
    server_name signup.mysite.com;
    return 301 https://$server_name$request_uri;
}
261
VBart

これをすべて1つのサーバーブロックに保持する場合は、これが正しい最も効率的な方法です。

server {
    listen   80;
    listen   [::]:80;
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

上記の他のすべて、「rewrite」または「if ssl_protocol」などを使用すると、速度が低下し、悪化します。

以下は同じですが、より効率的です。httpプロトコルで書き換えを実行するだけで、すべてのリクエストで$ scheme変数を確認する必要がなくなります。しかし、真剣に、それらを分離する必要がないほどのマイナーなものです。

server {
    listen   80;
    listen   [::]:80;

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}
123
DELETEDACC

新しいデュアルHTTPおよびHTTPSサーバー定義を使用している場合は、以下を使用できます。

server {
    listen   80;
    listen   [::]:80;
    listen   443 default ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($ssl_protocol = "") {
       rewrite ^   https://$server_name$request_uri? permanent;
    }
}

これは私にとってはうまくいくように見え、リダイレクトループを引き起こしません。

編集:

交換済み:

rewrite ^/(.*) https://$server_name/$1 permanent;

プラティックの書き直しラインで。

56
David Pashley

Host:リクエストヘッダーを保持し、 nginx pitfalls の「GOOD」の例に従う、さらに別のバリアント:

server {
    listen   10.0.0.134:80 default_server;

    server_name  site1;
    server_name  site2;
    server_name  10.0.0.134;

    return 301 https://$Host$request_uri;
}

結果は次のとおりです。 $server_nameの代わりに$Hostを使用すると、常にhttps://site1にリダイレクトされることに注意してください。

# curl -Is http://site1/ | grep Location
Location: https://site1/

# curl -Is http://site2/ | grep Location
Location: https://site2/


# curl -Is http://site1/foo/bar | grep Location
Location: https://site1/foo/bar

# curl -Is http://site1/foo/bar?baz=qux | grep Location
Location: https://site1/foo/bar?baz=qux
27
Peter

Cookieに「セキュア」を設定してください。そうしないと、HTTPリクエストで送信され、Firesheepなどのツールによって取得される可能性があります。

3
server {
    listen x.x.x.x:80;

    server_name domain.tld;
    server_name www.domian.tld;
    server_name ipv4.domain.tld;

    rewrite     ^   https://$server_name$request_uri? permanent;
}

これはうまくいくと思います。 x.x.x.xは、サーバーのIPを指します。 Plesk 12を使用している場合は、ディレクトリ「/var/www/vhosts/system/domain.tld/conf」内の「nginx.conf」ファイルを変更して、目的のドメインを作成できます。設定を保存した後、nginxサービスを再起動することを忘れないでください。

1
Caner SAYGIN

これが最も簡単な解決策だと思います。 HTTPSとWWW以外の両方のトラフィックをHTTPSとwwwのみに強制します。

server {
    listen 80;
    listen 443 ssl;

    server_name domain.tld www.domain.tld;

    # global HTTP handler
    if ($scheme = http) {
        return 301 https://www.domain.tld$request_uri;
    }

    # global non-WWW HTTPS handler
    if ($http_Host = domain.tld) {
        return 303 https://www.domain.tld$request_uri;
    }
}

編集-2018年4月:IFのないソリューションは私の投稿にあります https://stackoverflow.com/a/36777526/6076984

0
stamster