proxy_pass がパス パスに従って転送する場合の "/" 問題の詳細な説明

proxy_pass がパス パスに従って転送する場合の "/" 問題の詳細な説明

nginx で proxy_pass を設定するときに、^~ に従ってパスを一致させる場合は、proxy_pass の後の URL の最後の / に注意してください。 / が追加されると、それは絶対ルート パスと同等になり、nginx は location 内の一致するパス部分をプロキシしません。/ がない場合、一致するパス部分もプロキシされます。

たとえば、次の設定:

場所 ^~ /wangshibo/
{
proxy_cache js_cache;
proxy_set_header ホスト js.test.com;
proxy_pass http://js.test.com/;
}

上記の設定に示すように、要求された URL が http://servername/wangshibo/test.html の場合、http://js.test.com/test.html にプロキシされます。

このように設定すると

場所 ^~ /wangshibo/
{
proxy_cache js_cache;
proxy_set_header ホスト js.test.com;
proxy_pass http://js.test.com;
}

要求された URL は http://servername/wangshibo/test.html であり、http://js.test.com/wangshibo/test.html にプロキシされます。

もちろん、次の書き直しを使用して、/の機能を実装することもできます。

場所 ^~ /wangshibo/
{
proxy_cache js_cache;
proxy_set_header ホスト js.test.com;
/wangshibo/(.+)$ を書き換え /$1 区切り;
proxy_pass http://js.test.com;
}

ここに例があります

1) 最初の構成

[root@BJLX_16_202_V vhosts]# cat ssl-wangshibo.conf
上流の{
  サーバー 192.168.1.202:8080 max_fails=3 fail_timeout=30s;
}
  
サーバー{
  聞く 443;
  サーバー名 www.wangshibo.com;
  sslオン;
  
  ### SSL ログファイル ###
  access_log ログ/wangshibo_access.log;
  error_log ログ/wangshibo_error.log;
  
### SSL 証明書ファイル ###
  ssl_certificate ssl/wang.cer;  
  ssl_certificate_key ssl/wang.key;
  
  場所 /出席/ {
  proxy_pass http://at; //「/」を追加する必要はありません          
  proxy_next_upstream エラー タイムアウト invalid_header http_500 http_502 http_503;
  proxy_set_header ホスト $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
  proxy_redirect オフ;
    }
  
}

https://www.wangshibo.com/attendance/ と http://192.168.1.202:8080/attendance にアクセスした結果は一貫しています。

2) 2番目の構成

[root@BJLX_16_202_V vhosts]# cat ssl-wangshibo.conf
上流の{
  サーバー 192.168.1.202:8080 max_fails=3 fail_timeout=30s;
}
  
サーバー{
  聞く 443;
  サーバー名 www.wangshibo.com;
  sslオン;
  
  ### SSL ログファイル ###
  access_log ログ/wangshibo_access.log;
  error_log ログ/wangshibo_error.log;
  
### SSL 証明書ファイル ###
  ssl_certificate ssl/wang.cer;  
  ssl_certificate_key ssl/wang.key;
  
  位置 / {
  proxy_pass http://at/attendance/; //必ず「/」を追加してください            
  proxy_next_upstream エラー タイムアウト invalid_header http_500 http_502 http_503;
  proxy_set_header ホスト $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
  proxy_redirect オフ;
    }  
}

https://www.wangshibo.com と http://192.168.1.202:8080/attendance にアクセスした結果は一貫しています。

私たちが実現したい構成は次のとおりです。

192.168.1.27 はバックエンドの実際のサーバーであり、ポート 8080 は会社の EHR 人事システム ポートです。

このシステムにはWeChatインターフェースアクセス、つまりhttp://ehr.wang.com/attendanceとhttp://ehr.wang.com/appが含まれるため

社内システムであるため、セキュリティ上の理由から、以下の要件が必要です。

1) EHR人事システムにログインする際は、イントラネットログイン、つまりhttp://192.168.1.27:8080を使用する必要があります。アクセスする前に会社のVPNにログインする必要があります。
2) 外部ネットワークを使用して、WeChat インターフェース http://ehr.wang.com/attendance および http://ehr.wang.com/app にログインします。つまり、解決されたドメイン名を使用してログインします。
3) http://ehr.wang.com にアクセスし、https://ehr.wang.com/attendance にリダイレクトします。

[root@BJLX_4_21_P vhosts]# cat ehr.conf
サーバー{
  聞く 80;
  サーバー名 ehr.wang.com;
  
  access_log ログ/ehr_access.log;
  error_log ログ/ehr_error.log;
 
  301 https://$server_name$request_uri を返します。   
}
 
[root@BJLX_4_21_P vhosts]# cat ssl-ehr.conf
上流EHR{
  サーバー 192.168.1.27:8080 max_fails=3 fail_timeout=30s;
}
 
サーバー{
  聞く 443;
  サーバー名 ehr.wang.com;
  sslオン;
 
  ### SSL ログファイル ###
  access_log ログ/ehr_access.log;
  error_log ログ/ehr_error.log;
 
### SSL 証明書ファイル ###
  ssl_certificate ssl/wang.cer;   
  ssl_certificate_key ssl/wang.key; 
  #ssl_session_timeout 5分;
 
  位置 / {
    301 https://ehr.wang.com/attendance を返します。
  }
 
  場所 /出席/ {
  proxy_pass http://ehr;
  proxy_next_upstream エラー タイムアウト invalid_header http_500 http_502 http_503;
  proxy_set_header ホスト $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto https;
  #proxy_set_header X-Forwarded-Proto https;
  proxy_redirect オフ;
  }
 
  場所 /app/ {
  proxy_pass http://ehr;
  proxy_next_upstream エラー タイムアウト invalid_header http_500 http_502 http_503;
  proxy_set_header ホスト $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto https;
  #proxy_set_header X-Forwarded-Proto https;
  proxy_redirect オフ;
  }
 }

知らせ:

ブラウザ(http)からオリジンステーションの実サーバーへのアクセスは、Nginxリバースプロキシ層(https)を経由する必要があるため

proxy_set_header X-Forwarded-Proto https; の行をコメントアウトする必要があります。そうしないと、上記の構成は無効になります。

中間にプロキシ層がなく、nginx が実際のサーバー上で直接リバースプロキシされている場合 (つまり、ローカル nginx がローカルサーバーのポート 8080 にリバースプロキシされている場合)、このパラメーターは無効です (検証済み)

HTTP ヘッダー フィールド (proxy_set_header) のリストと説明

HTTP ヘッダー フィールドは、HTTP プロトコルのリクエストとレスポンスのヘッダー情報です。実際には、HTTP 通信の動作パラメータであり、Web サーバーとブラウザーに通信の処理方法を指示します。

HTTP ヘッダーは、要求メッセージまたは応答メッセージの 2 行目 (最初の行は要求行または応答行) から始まり、2 つの CR-LF 文字グループ (CR: 復帰、\r、LF: 改行 \n) で終わります。

各 HTTP ヘッダーは文字列形式であり、キーと値のペアはコロンで区切られ、複数の HTTP ヘッダーは CR-LF 文字グループで区切られます。

一部の HTTP ヘッダーには、user-agent、server、via などのコメントを含めることができます。ただし、これらのコメントはサーバーまたはブラウザによって無視されます。IETF 組織は、RFC2616 仕様でいくつかのコア HTTP ヘッダーを定義しています。
これらの HTTP ヘッダーは、すべての HTTP ベースのソフトウェアで実装する必要があり、その他の更新および拡張されたヘッダー フィールドも HTTP ベースのソフトウェアで実装する必要があります。もちろん、各ソフトウェアは独自のヘッダー フィールドを定義することもできます。

一方、RFC2616仕様では、各HTTPヘッダーの長さやHTTPヘッダーの数に制限はありませんが、パフォーマンスとセキュリティ上の理由から、ほとんどのサーバーはApache 2.3などの独自の規制を設けています。
各 HTTP ヘッダーは 8190 バイトを超えず、各リクエストは 100 個の HTTP ヘッダーを超えないことが規定されています。

リクエストを送信するときに含まれる可能性のあるさまざまな HTTP ヘッダーとその説明を見てみましょう。

標準リクエストヘッダー --

Accept: ブラウザ(またはその他のHTTPベースのクライアントプログラム)が受け入れ可能なコンテンツタイプ(Accept: text/plainなど)

Accept-Charset: ブラウザが認識できる文字セット。例: Accept-Charset: utf-8

Accept-Encoding: ブラウザが処理できるエンコード方式。ここでのエンコード方式は文字セットとは異なることに注意してください。ここでのエンコード方式は通常、gzip、deflate などを指します。たとえば、Accept-Encoding: gzip, deflate

Accept-Language: ブラウザが受け入れる言語。これは実際にはユーザーの言語地域です。たとえば、簡体字中国語の場合は Accept-Language: zh-CN です。

認証: HTTP では、サーバーは一部のリソースを認証して保護できます。これらのリソースにアクセスするには、ユーザー名とパスワードを指定する必要があります。ユーザー名とパスワードは Authorization ヘッダーに含まれています。形式は、「ユーザー名:パスワード」文字列の base64 エンコードです。例: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==、basic は基本認証方法を使用することを意味します。QWxhZGRpbjpvcGVuIHNlc2FtZQ== を base64 でデコードすると、「Aladdin:open sesame」になります。

Cache-Control: このディレクティブはリクエストとレスポンスの両方に存在し、キャッシュシステム (サーバーまたはブラウザ上) にキャッシュの処理方法を指示するために使用されます。このヘッダーフィールドは、特にキャッシュを使用してパフォーマンスを向上させたい場合やコンテンツが多い場合に非常に重要であるため、次のブログ投稿で主に紹介したいと思います。

接続: ユーザー エージェント (通常はブラウザー) が使用する接続方法をサーバーに通知します。値はkeep-aliveとcloseです。 http1.1 のデフォルト設定は keep-alive です。キープアライブは、ブラウザとサーバー間の通信接続が継続的に保存され、すぐに閉じられないことを意味します。一方、クローズは、応答後すぐに閉じられます。ただし、ここで注意すべき点は、HTTP がステートレスであると言う場合、それはキープアライブが使用されるかどうかとは関係がないということです。キープアライブが HTTP のステートレス機能の改良であるとは考えないでください。

Cookie: ブラウザがサーバーにリクエストを送信するか、サーバーがブラウザに Cookie を添付すると、Cookie がここに配置されます。例: Cookie:user=admin

Content-Length: リクエストのリクエスト本体のメモリ長 (バイト単位)。リクエスト ボディは、HTTP ヘッダーの後の 2 つの CR-LF 文字グループの後のコンテンツを参照します。共通コンテンツには、POST によって送信されたフォーム データが含まれます。Content-Length には、リクエスト ラインと HTTP ヘッダーのデータ長は含まれません。

Content-MD5: base64 を使用してエンコードされたリクエスト本文の MD5 チェックサム。例: Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==

Content-Type: リクエスト本文のコンテンツの MIME タイプ。通常、POST および PUT メソッド リクエストでのみ使用されます。例: Content-Type: application/x-www-form-urlencoded

日付: リクエストが送信された GMT 時間。例: 日付: 火曜日、1994 年 11 月 15 日 08:12:31 GMT

Expect: サーバーのいくつかの特別な機能を使用する必要があることを示します。 (この点についてはよく分かりません)

送信元: このリクエストを送信するユーザーのメール アドレス。例: 送信者: [email protected]

ホスト: サーバーのドメイン名または IP アドレス。共通ポートでない場合は、ポート番号も含まれます。例: ホスト: www.some.com:182

If-Match: 通常、PUT メソッドを使用してサーバー リソースを更新するリクエストで使用されます。これは、要求されているリソースのタグがこの If-Match のタグと異なるかどうかをサーバーに問い合わせることを意味します。同じ場合は、サーバー上のリソースがまだ古く、今すぐ更新できることがわかります。異なる場合は、リソースが更新されており、再度更新する必要がないことがわかります (そうでない場合、他の人が行った変更が上書きされる可能性があります)。

If-Modified-Since: 要求されたリソースが特定の時間以降に変更されたかどうかをサーバーに問い合わせます。変更されていない場合、サーバーは 304 ステータスを返して、ブラウザーにブラウザー自身のローカル キャッシュを使用するように指示します。変更されている場合は、200 を返して新しいリソースを送信します (もちろん、リソースが存在しない場合は 404 を返します)。

If-None-Match: If-Modified-Since と同様の目的を持ちますが、時間に基づいて決定されるのではなく、ETag と呼ばれるものに基づいて決定されます。次のブログではetagについて紹介したいと思います。

If-Range: リソースが変更されていない場合 (If-Range の後に指定された Etag に基づいて)、リソースの不足している部分をブラウザーに送信するようにサーバーに指示します。リソースが変更されている場合は、リソース全体のコピーをブラウザーに再送信します。

If-Unmodified-Since: 現在要求されているリソースが特定の時間以降変更されていないかどうかをサーバーに問い合わせます。

Max-Forwards: プロキシ サーバーまたはゲートウェイで要求情報が転送される回数を制限します。

プラグマ: 値は 1 つだけ、つまり no-cache しかないようです。 Pragma:no-cache は cache-control:no-cache と同じですが、cache-control:no-cache は http1.1 で明示的に指定されているのに対し、Pragma:no-cache は http1.0 と 1.1 で使用できます。

Proxy-Authorization: Authorization ヘッダーと同様に、プロキシに接続するときに使用される認証情報。例: Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

範囲: HTTP ヘッダーでは、「範囲」という単語は、「リソースのバイト形式のデータの順序付けられた配列、およびデータの特定のセクションを取得すること」を意味します。 Range ヘッダーは、要求されたリソースの特定の値から特定の値までのデータを示します。たとえば、Range: bytes=500-999 は、要求されたリソースの 500 バイトから 999 バイトまでのデータを示します。これを使用することで、データのセグメント化されたダウンロードとマルチスレッドのダウンロードが実現されます。

リファラー: 現在要求されている URL が参照されているアドレスを指します。たとえば、www.a.com/index.html ページで www.b.com を指すハイパーリンクをクリックすると、www.b.com のリクエストの Referer は www.a.com/index.html になります。私たちがよく目にする画像のホットリンク保護は、このように実装されています。

アップグレード: サーバーに別のプロトコルへのアップグレードを要求します。例: アップグレード: HTTP/2.0、SHTTP/1.3、IRC/6.9、RTA/x11

User-Agent: 通常はユーザーのブラウザ関連の情報。例: User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0

Via: リクエストがターゲット サーバーに送信される前に通過するプロキシまたはゲートウェイを記録するために使用されます。たとえば、リクエストがブラウザから発信され (http/1.0 が使用されていると仮定)、SomeProxy という内部プロキシに送信され、次に www.somenet.com というパブリック プロキシ (http/1.1 を使用) に転送され、最終的にターゲット サーバー www.someweb.com に転送されます。someweb.com で受信される via ヘッダーは、次のようになります: via:1.0 someProxy 1.1 www.someweb.com (apache 1.1)

警告: 警告情報を記録します。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginx での proxy_pass の使用に関する質問
  • nginx proxy_pass リバース プロキシ設定で URL の後に / を追加する場合と追加しない場合の違いの紹介
  • Nginx サーバーリバースプロキシ proxy_pass 設定方法の説明
  • nginx proxy_pass ディレクティブ '/' の使用に関する注意事項

<<:  MySQL 5.7.13 winx64 のインストールと設定方法のグラフィック チュートリアル (win10)

>>:  Vue の 2 択タブバー切り替えの新しいアプローチ

推薦する

MySQL 8.0 における MySQL のインストールと新しいパスワード認証方法の詳細な説明

1. はじめにOracle が MySQL 8.0GA をリリースしました。海外での GA はリリー...

VMware vCenter 6.7 のインストール プロセス (グラフィック チュートリアル)

背景当初は VMware の公式 Web サイトから 6.7 Vcenter をダウンロードしたかっ...

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒント

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒントbashに詳しい人なら、hi...

MySQL方言の簡単な紹介

データベースはさておき、人生における方言とは何でしょうか?方言とは、ある場所特有の言語です。他の場所...

CentOS7 は rpm を使用して MySQL 5.7 をインストールするチュートリアル図

1. 4つのrpmパッケージをダウンロードする mysql-コミュニティクライアント-5.7.26-...

mysql order by in の文字順序の詳細な説明 (推奨)

//MySQL ステートメント SELECT * FROM `MyTable` WHERE `id...

Vueは完全な選択機能を実装しています

この記事の例では、完全な選択機能を実装するためのVueの具体的なコードを参考までに共有しています。具...

HTML は Double 11 クーポン取得を実装します (クーポン取得ページを開く時間を設定します)

さっそく、コードを直接投稿します。具体的なコードは次のとおりです。 <!DOCTYPE htm...

選択にスタイルを追加するための純粋な CSS (スクリプトなし) 実装

通常は ul、li を介して選択のデフォルト スタイルを変更して、実現をシミュレートします。このよう...

CentOS はローカル yum ソースを使用して LAMP 環境を構築するグラフィック チュートリアル

この記事では、ローカル yum ソースを使用して CentOS 上に LAMP 環境を構築する方法に...

Windows での自動展開に Jenkins を使用するチュートリアル図

今日は、Jenkins + powershell スクリプトを使用して、.NET CORE スクリプ...

CSSを使用して、頻繁に表示される奇妙なボタンを簡単に実装します。

背景グループでは、CSS を使用してインセット コーナー ボタンを実装する方法や、矢印付きのボタンを...

Vueはデジタル千単位区切り形式をグローバルに実装します

この記事の例では、Vue がデジタル 3 桁区切り形式をグローバルに実装するための具体的なコードを参...

MySQL 8.0.12 簡単インストールチュートリアル

この記事では、MySQL 8.0.12のインストールチュートリアルを参考までに紹介します。具体的な内...

非ルートユーザーを使用してDockerコンテナでスクリプト操作を実行する

アプリケーションをコンテナ化した後、Docker コンテナを起動すると、デフォルトで root ユー...