Nginx:1つのパスでSSLを強制し、他のパスで非SSLを強制します


27

Nginx confファイルを設定して、サイトのパスの1つのみでSSLを強制し、その他すべてのパスで非SSLを強制するにはどうすればよいですか?

たとえば、/ userの下のすべてのURLをhttpsにしたいが、残りのURLはすべてhttpにしたい。

最初の部分については:

rewrite ^/user(.*) https://$http_host$request_uri?;

「if」は使いたくありません。私はそれが操作の順序を利用すると仮定しますが、私はループになりたくないです。

回答:


38

nginx構成では、2つの「サーバー」領域が必要です。1つはポート80、もう1つはポート443(非SSLおよびSSL)用です。非SSL Webサイトに場所を追加して、SSLページにリダイレクトするだけです。

server {
    root /var/www/
    location / {
    }
    location /user {
        rewrite ^ https://$host$request_uri? permanent;
    }
}

/ userで終わるすべてのトラフィックをhttps://サーバーに転送します。

次に、443サーバーで反対の操作を行います。

server {
    listen 443;
    root /var/www/
    location / {
        rewrite ^ http://$host$request_uri? permanent;
    }
    location /user {
    }
}

2
このアプローチは優れていますが、いくつかの一般的な落とし穴、具体的には「ロケーションブロック内のルート」と「書き換えの課税」に
分類されます

1
編集しました。それはOKに見えますか?listen 80を取り出し、http_hostを追加しました。
-pbreitenbach

この構成では、ユーザーがサイトのページをナビゲートするときにssl / non-sslから、またはssl / non-sslに接続が切り替わり、URLの/usersslは他のすべてのURLで開始されます。その結果、ユーザーhttps://www.example.com/がブラウザのアドレスバーに明示的に入力しても、結果のページはになりますhttp://www.example.com/。この回答で説明されている設定によって達成されるように、ssl / non-ssl間にauto-url-rewriteを実装する方法はありますが、アドレスバーにユーザーが明示的に入力した場合は明示的なsslリクエストを尊重しますか?ありがとう!
さようなら

@goodbyeeraええ。ユーザーが特定の領域でSSLを使用することを強制することである場合、そこでプロトコルをオーバーライドできますが、443サーバー構成から書き換えコマンドを削除するだけで、他のすべての場所でそれらを尊重できます。もちろん、今ではセキュリティで保護された部分に行ったとき、他の場所に行ってもSSLを使用してブラウジングしていますが、ユーザーは最初からSSLを使用することを選択できます。
チャックドライ

13

Nginxでは、同じserverブロック内でHTTPとHTTPSの両方を処理できます。したがって、両方のディレクティブを複製する必要はなく、保護したいパスをリダイレクトできます

server {
  listen 80 default_server;
  listen 443 ssl;
  ... ssl certificate and other configs ...

  location /user {
    if ($scheme = 'http') {
      rewrite ^ https://$http_host$request_uri? permanent;
    }
  }

  ... your basic configuration ...
}

単純なHTTPを壊すので、そこに行を置かないでくださいssl on

オプションで、他のすべてのリクエストをHTTPSからHTTPに同じ方法でリダイレクトできます。

if ($scheme = 'https') {
  rewrite ^ http://$http_host$request_uri? permanent;
}

更新:Alexey Tenがコメントセクションで親切に指摘しているように、scheme各リクエストをチェックすることはあまり良い考えではありません。宣言的な方法でnginxを構成する必要があります。この場合、によるリダイレクトを使用して2つのサーバーブロックを宣言しlocation、共通のロジックを別のファイルに移動しますinclude。したがって、GruffTechの答えの方が優れています。


2
すべてのリクエストに対してnginxチェックスキームを作成することは効果的ではありません。
アレクセイ10 14年

1
質問は3年前に回答されたことは知っていますが、次第にやることに苦労しながらそれを見つけ、私の結果を私の手順に従う人と共有したかっただけです。
Hnatt 14年


1
@AlexeyTenは、「ifの使用を避けられない場合」ではありませんか?ディレクティブを複製せずにHTTPとHTTPSに同じ設定を行う他の方法はありますか?
Hnatt 14年

2
include一般的なディレクティブにはディレクティブを使用します。いくつかの複製は問題ありません。
アレクセイ10 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.