Webサーバー上のすべてのhttp要求をhttps要求に書き換えたいので、次のことから始めました。
サーバー{ 80を聞きます。 場所/ { ^(。*)https://mysite.com$1パーマネントを書き換えます。 } ...
1つの問題は、これによりサブドメイン情報(node1.mysite.com/folderなど)が削除されることです。すべてをhttpsに再ルーティングしてサブドメインを維持するために上記を書き換えるにはどうすればよいですか。
Webサーバー上のすべてのhttp要求をhttps要求に書き換えたいので、次のことから始めました。
サーバー{ 80を聞きます。 場所/ { ^(。*)https://mysite.com$1パーマネントを書き換えます。 } ...
1つの問題は、これによりサブドメイン情報(node1.mysite.com/folderなど)が削除されることです。すべてをhttpsに再ルーティングしてサブドメインを維持するために上記を書き換えるにはどうすればよいですか。
回答:
この質問に対する私の最初の答えは特定の時間に正しかったことが判明しましたが、それは別の落とし穴になりました-最新の状態に保つには、課税書き換えの落とし穴を確認してください
私は多くのSEユーザーによって修正されたので、信用は彼らにありますが、より重要なことは、正しいコードです:
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name my.domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always;
[....]
}
$host
代わりに使用する必要があることに注意してください$server_name
。
注:これを行うための最良の方法はhttps://serverfault.com/a/401632/3641によって提供されましたが、ここで繰り返します:
server {
listen 80;
return 301 https://$host$request_uri;
}
最も単純な場合、ホストは送信先のサービスに固定されます。これにより、ブラウザーへの301リダイレクトが行われ、ブラウザーのURLがそれに応じて更新されます。
以下は、正規表現のために非効率的な前の回答です。@ kmindiで示されているように、単純な301は素晴らしいです
私はnginx 0.8.39以上を使用しており、次を使用しました:
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
クライアントに永続的なリダイレクトを送信します。
最善かつ唯一の方法は、次のようにHTTP 301 Moved Permanentlyリダイレクトを使用することです。
server {
listen [::]:80;
return 301 https://$host$request_uri;
}
恒久的移動HTTP 301すでに述べによれば、評価すべき正規表現が存在しないため、リダイレクトはまた、最も効率的であるpitfails。
新しいHTTP 308 Moved PermanentlyはRequestメソッドを保持し、主要なブラウザでサポートされています。たとえば、を使用308
すると、ブラウザはリダイレクトリクエストのリクエストメソッドをからPOST
に変更できなくなりますGET
。
ホスト名とサブドメインを保持する場合、これが方法です。
DNSがない場合でも、ローカルで使用しているため、これは機能します。たとえばをリクエストしてhttp://192.168.0.100/index.php
おり、正確ににリダイレクトされますhttps://192.168.0.100/index.php
。
listen [::]:80
ホストに使用するのは、にbindv6only
設定しているためfalse
、ipv4ソケットにもバインドするためです。listen 80
IPv6が必要ない場合、または他の場所にバインドする場合に変更します。
Saif Bechanのソリューションserver_name
では、私の場合はlocalhostを使用していますが、ネットワーク経由では到達できません。
Michael Nealeからの解決策は良いですが、pitfailsによると、リダイレクト301を使用したより良い解決策があります;)
サーバーブロック内では、次のこともできます。
# Force HTTPS connection. This rules is domain agnostic
if ($scheme != "https") {
rewrite ^ https://$host$uri permanent;
}
新しいサブドメインが常に作成されるため、上記は機能しませんでした。たとえば、約30のサブドメインのAAA.example.com BBB.example.com。
最後に、以下で動作する設定を取得しました:
server {
listen 80;
server_name _;
rewrite ^ https://$host$request_uri? permanent;
}
server {
listen 443;
server_name example.com;
ssl on;
ssl_certificate /etc/ssl/certs/myssl.crt;
ssl_certificate_key /etc/ssl/private/myssl.key;
ssl_prefer_server_ciphers on;
# ...
# rest of config here
# ...
}
301 https://*/
ここの他の回答で要求を途中で返すかキャンセルします。server_name _;
と$host
は、トリックをした答えでした。+1
_
実際のドメインに置き換えることをお勧めします。たとえば、.domain.com
2台のサーバーがあり、nginxが誤ってサーバーの1つをデフォルトサーバーにリダイレクトしていました。
私は非常に重要な修正を加えてずっと前に正解にコメントを投稿しましたが、この修正を独自の回答で強調する必要があると感じています。セキュリティで保護されていないHTTPをセットアップし、ユーザーコンテンツを期待している場合、フォームを持っている場合、APIをホストしている場合、またはWebサイト、ツール、アプリケーション、またはユーティリティをサイトに話しかけるように構成している場合、以前の回答はどれも安全ではありません。
この問題はPOST
、サーバーに要求が行われたときに発生します。サーバーの応答がプレーン30x
リダイレクトである場合、POSTコンテンツは失われます。何が起こるかというと、ブラウザ/クライアントがSSLに要求をアップグレードするが、ということですダウングレードPOST
にGET
要求。POST
パラメータが失われ、正しくない要求は、サーバーに行われます。
解決策は簡単です。HTTP 1.1 307
リダイレクトを使用する必要があります。これはRFC 7231 S6.4.7で詳しく説明されています。
Note: This status code is similar to 302 (Found), except that it
does not allow changing the request method from POST to GET. This
specification defines no equivalent counterpart for 301 (Moved
Permanently) ([RFC7238], however, defines the status code 308
(Permanent Redirect) for this purpose).
受け入れられたソリューションから適応したソリューションは307
、リダイレクトコードで使用することです。
server {
listen 80;
server_name my.domain.com;
return 307 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name my.domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
[....]
}
私は次のようにそれをすることができました:
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;
}
}
あなたの場合はreturn 301 https://$host$request_uri;
ポート80上のデフォルトの応答として、その後、サーバーは、遅かれ早かれ、オープンプロキシのリストに得ることができます[1]、インターネット上の他の場所でトラフィックを送信するために悪用される始めます。ログがこのようなメッセージでいっぱいになった場合、あなたはそれがあなたに起こったことを知っています:
42.232.104.114 - - [25/Mar/2018:04:50:49 +0000] "GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1" 301 185 "http://www.ioffer.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Hotbar 4.1.8.0; RogueCleaner; Alexa Toolbar)"
問題は、次の$host
ように、ブラウザーがHost
ヘッダーで送信するものや、HTTPの開始行からのホスト名でさえもエコーバックすることです。
GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1
その問題のため、ここでの他のいくつかの答えはの$server_name
代わりに使用することをお勧めします$host
。$server_name
常にあなたがserver_name
宣言に入れたものを評価します。しかし、そこに複数のサブドメインがある場合、またはワイルドカードを使用する場合、宣言の後の最初のエントリ$server_name
のみを使用し、さらに重要なことにワイルドカードをエコーバックするだけなので、機能しません。server_name
それでは、セキュリティを維持しながら複数のドメインをサポートする方法は?自分のシステムでは、私がすることで、このジレンマに対処してきた最初の上場default_server
使用していないブロックを$host
、次に行い、ワイルドカードのブロックをリスト:
server {
listen 80 default_server;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
(2番目のブロックに複数のドメインをリストすることもできます。)
この組み合わせにより、example.com
一致しないドメインはハードコーディングされた場所(常に)にリダイレクトされ、自分のドメインに一致するドメインは適切な場所に移動します。サーバーはオープンプロキシとしては役に立たないので、トラブルを引き付けることはありません。
もしあなたがおかしいと感じているなら、私はあなたのdefault_server
ブロックがあなたの正当なドメインのどれにもマッチせず、不快な何かを提供することもできると思います。。。。
[1]技術的に「プロキシ」は間違った言葉です。サーバーが外に出ず、クライアントへのリクエストを実行せず、リダイレクトを送信するだけですが、正しい言葉が何であるかわかりません。また、目標が何であるかわかりませんが、ログがノイズでいっぱいになり、CPUと帯域幅を消費するため、停止することもできます。
誰も実際に100%正しいとは思わないようです。ポート80リクエストをWebサーバー全体で443相当に送信するには、server_nameディレクティブではなくlistenディレクティブを使用して、キャッチオール名を指定する必要があります。https://nginx.org/en/docs/http/request_processing.htmlも参照してください
サーバー{ 80のデフォルトをリッスンします。 listen [::]:80 default; return 307 https:// $ host $ request_uri; }
また、default.confが既存のvhostを返すという問題が頻繁に発生するため、/ etc / nginx / conf.d /の内容を確認してください。nginxの問題を処理する私の順序は、常にデフォルトファイルを移動し、行ごとにコメントアウトして元に戻すことから始まります。