4.7.4 注意事項
- 〈この項の構成〉
(1) 基本的な注意事項
-
リバースプロキシはリクエストURLのパターンによって機能を設定します。このため,特定のリクエストはリバースプロキシとしてほかのバックエンドサーバに転送,それ以外のリクエストはリバースプロキシ自身がWebサーバとして応答するという設定もできます。しかし,このような設定は,リクエストがリバースプロキシかWebサーバかどちらで処理したかがわかりにくくなります。したがって,リバースプロキシを使用する場合は次のような設定にして,すべてのリクエストをリバースプロキシからバックエンドサーバへ転送することを推奨します。
ProxyPass / http://転送先バックエンドサーバアドレス/
リバースプロキシとWebサーバを共用する場合は,バーチャルホストで機能を分けた運用ができます。
-
リバースプロキシでは,クライアントから受信したHostヘッダの値をX-Forwarded-Hostヘッダに格納し,Hostヘッダの値をProxyPassディレクティブの指定値に変換してバックエンドサーバへ転送します。このため,バックエンドサーバ側のアプリケーションでクライアントが送信したHostヘッダの値を参照する場合は,リバースプロキシが送信したX-Forwarded-Hostヘッダの値を参照してください。ただし,ProxyPreserveHostディレクティブの値にOnを設定している場合は,リバースプロキシが送信したHostヘッダの値をそのまま参照してください。
-
リバースプロキシを経由してバックエンドサーバにアクセスする場合,バックエンドサーバが提供するHTMLコンテンツでのリンク先は,バックエンドサーバ上のURLではなく,リバースプロキシにアクセスされるURLを指定する必要があります。このほか,画像やスタイルシートなどのコンテンツの参照先URLを記述する場合も同じように注意が必要です。
(例)
次の状態にあるときに,index.htmlからindex2.htmlへリンクを張るとします。
-
リバースプロキシ側でProxyPassディレクティブの値が /before/ http://バックエンドサーバのアドレス/after/ と指定されている。
-
バックエンドサーバ側でindex.htmlとindex2.htmlが同じディレクトリ内(/after/以下)に存在する。
この場合のindex.htmlの記述方法とアクセス可否の関係を次に示します。
表4‒10 リンクの記述方法とリンク可否の関係 リンクの記述
リンクをクリックしたときのアクセス可否
<A HREF="index2.html">リンク</A>
○
<A HREF="/before/index2.html">リンク</A>
○
<A HREF="http://リバースプロキシのアドレス/before/index2.html">リンク</A>
○
<A HREF="/after/index2.html">リンク</A>
×
-
-
リバースプロキシは,HTTPバージョン0.9をサポートしていません。
-
11-20以降では,CustomLogディレクティブで指定するログのフォーマットで%{header_name}iを指定した場合,リバースプロキシで付加するリクエストヘッダはログに出力されません。詳細は「付録C 旧バージョンからの移行に関する注意点」を参照してください。
-
リバースプロキシでは,クライアントからリクエスト受信時の送信元IPアドレスをX-Forwarded-Forヘッダに格納し,バックエンドサーバへ転送します。このため,バックエンドサーバ側のアプリケーションでクライアントの送信元IPアドレスを参照する場合は,リバースプロキシが送信したX-Forwarded-Forヘッダを参照してください。
-
リバースプロキシでは,バックエンドサーバに接続したコネクションを維持したまま再利用する,コネクションプール方式を採用しています。
(2) ProxyPassディレクティブに関する注意事項
-
ProxyPassディレクティブで指定するパス名とリクエストURLは完全に等しいか,パス名がリクエストURLの先頭から含まれていれば,適合と判断します。
ただし,パス名の終端が/(スラッシュ)でない場合,リクエストURLと完全に等しいかまたは先頭からディレクトリとして含まれていれば適合と判断します。
適合すると,ProxyPassディレクティブに指定したパス名にリクエストURLの先頭からパス名と等しい部分を除いた残りの部分を追加してリクエストを転送します。
ProxyPassディレクティブに指定するパス名は終端を/(スラッシュ)で閉じたものを指定してください。次にProxyPassディレクティブの指定とリクエストの関係を次に示します。
表4‒11 ProxyPassディレクティブの指定とリクエストの関係 ProxyPassディレクティブの指定例
リクエスト
適合可否
リクエスト転送先
ProxyPass /abc/ http://backend.example.com/
http://リバースプロキシのアドレス/abc/
○
http://backend.example.com/
http://リバースプロキシのアドレス/abc
×
−
http://リバースプロキシのアドレス/abc/def
○
http://backend.example.com/def
ProxyPass /abc http://backend.example.com/
http://リバースプロキシのアドレス/abc
○
http://backend.example.com/
http://リバースプロキシのアドレス/abc/
○
http://backend.example.com//
http://リバースプロキシのアドレス/abc/def
○
http://backend.example.com//def
-
ProxyPassディレクティブを複数指定し,リクエストURLが複数のパス名に一致した場合,先に指定したProxyPassディレクティブが有効になります。
(例)
/abc/def/へのリクエストを処理するバックエンドサーバ:backend1.example.com
/abc/def/以外の/abc/へのリクエストを処理するバックエンドサーバ:backend2.example.com
ほかのすべてのリクエストを処理するバックエンドサーバ:backend3.example.com
このように設定するには次の順序で指定してください。
ProxyPass /abc/def/ http://backend1.example.com/ ProxyPass /abc/ http://backend2.example.com/ ProxyPass / http://backend3.example.com/
-
ProxyPassディレクティブの指定によるリクエストURLはWebサーバの機能である自プロセス内の該当ファイルの検索より先に転送します。したがって,リクエストURLに適合するファイルがある場合でも,ProxyPassディレクティブのパス名に適合すれば,バックエンドサーバへのリクエストに変換して転送します。
-
/(スラッシュ)で閉じていないディレクトリを指定したリクエストURLの場合,リバースプロキシではリダイレクトを応答しません。
- (例)ProxyPass /ab/ http://backend.example.com/ の場合
-
リクエストがhttp://リバースプロキシのアドレス/abのとき,適合していないと判断して,リバースプロキシ内に/abがなければ,「404 Not Found」を返します。
-
ProxyPassディレクティブの転送先URLが,先に定義しているProxyPassディレクティブの転送先URLに含まれる場合,それらのProxyPassディレクティブはキーで指定された値を共有します。そのため,あとで定義しているProxyPassディレクティブではキーの値を指定できません。
(例)
ProxyPass /test1/ http://backend.example.com:81/AAA/ … 1. ProxyPass /test2/ http://backend.example.com:81/AAA/BBB/ timeout=10 … 2.
2.のProxyPassディレクティブの転送先URLは,1.の転送先URLに含まれるため,1.と2.はキーで指定された値を共有しています。あとで指定した2.ではキーの値を指定できません。
(3) ProxyPassReverseディレクティブに関する注意事項
-
ProxyPassReverseディレクティブに指定したURLとバックエンドサーバから受信したLocationヘッダの値は,完全に等しいかまたはURLがリクエストURLの先頭から含まれていれば,適合と判断します。適合すると,アドレスをリバースプロキシとして,ProxyPassReverseディレクティブの指定に従って,クライアントに送信します。
- (例)バックエンドサーバからの応答のLocationヘッダが,Location: http://バックエンドサーバのアドレス/docs/memo/の場合
-
ProxyPassReverseディレクティブの指定が,
ProxyPassReverse /path/ http://バックエンドサーバのアドレス/docs/
と指定されていれば,クライアントに返すLocationヘッダは
Location: http://リバースプロキシのアドレス/path/memo/
となります。
ProxyPassReverseディレクティブを複数指定した場合,先に指定した方が有効になります。
-
リバースプロキシがProxyPassReverseディレクティブの設定値に従ってLocationヘッダの値を変換してクライアントに転送する際,Locationヘッダの値のスキームは現在のコネクションで使用しているものを設定します。例えば,httpでアクセスしている場合,httpを設定します。このため,httpでアクセスしている場合にLocationヘッダでhttpsにリダイレクトさせるときは,バックエンドサーバ側でリバースプロキシのホスト名をLocationヘッダの値に設定しておくなどしてProxyPassReverseディレクティブの値と一致しないようにしてください。
(4) HWSProxyPassReverseCookieディレクティブに関する注意事項
-
HWSProxyPassReverseCookieディレクティブは,バックエンドサーバが応答したSet-Cookieヘッダを変換する場合に指定します。HWSProxyPassReverseCookieディレクティブに,ProxyPassディレクティブのパス名と同じ値を指定することで,ProxyPassディレクティブ単位に設定できます。
-
リバースプロキシのディレクティブ指定が次のような場合のSet-Cookieヘッダの変換規則について説明します。
ProxyPass /front/ http://backend.example.com/ HWSProxyPassReverseCookie /front/
表4‒12 Set-Cookieヘッダの変換規則 項番
クライアントに応答するSet-Cookieヘッダ
バックエンドサーバが応答するSet-Cookieヘッダ
変換規則の説明
1
Set-Cookie: 〜; path=/front/
Set-Cookie: 〜; path=/
バックエンドサーバが応答するSet-Cookieヘッダにドメイン名が指定されていない場合は,Set-Cookieヘッダのパス名/(スラッシュ)を/front/に置き換えます。
2
Set-Cookie: 〜; path=/front/
Set-Cookie: 〜; domain=backend.example.com; path=/
バックエンドサーバが応答するSet-Cookieヘッダのドメイン名が,ProxyPassディレクティブで指定した転送先URLのドメイン名と完全に一致している場合は,Set-Cookieヘッダのパス名/(スラッシュ)を/front/に置き換えます。また,Set-Cookieヘッダのドメイン名を削除してクライアントに返します。
3
Set-Cookie: 〜; domain=.example.com; path=/
Set-Cookie: 〜; domain=.example.com; path=/
バックエンドサーバが応答するSet-Cookieヘッダのドメイン名が,.(ピリオド)から始まるドメイン名である場合は,バックエンドサーバが応答したSet-Cookieヘッダをそのままクライアントに返します。
4
Set-Cookie: 〜; domain=other.example.com; path=/
Set-Cookie: 〜; domain=other.example.com; path=/
バックエンドサーバが応答するSet-Cookieヘッダのドメイン名がProxyPassディレクティブで指定した転送先URLのドメイン名と異なる場合は,バックエンドサーバが応答したSet-Cookieヘッダをそのままクライアントに返します。
5
Set-Cookie: 〜
Set-Cookie: 〜
バックエンドサーバが応答するSet-Cookieヘッダにドメイン名およびパス名が指定されていない場合は,バックエンドサーバが応答したSet-Cookieヘッダをそのままクライアントに返します。
-
リバースプロキシのディレクティブ指定が次の場合に,バックエンドサーバが応答したSet-Cookieヘッダのパス名を変換する規則について説明します。
ProxyPass /front/ http://backend.example.com/abc/def/ HWSProxyPassReverseCookie /front/
-
バックエンドサーバが返すSet-Cookieヘッダのパス名が/abc/def/ghi/の場合
ProxyPassディレクティブの転送先URLのパス名部分が,Set-Cookieヘッダのパス名に前方から一致する場合は,一致したパス名部分をProxyPassディレクティブのパス名で置き換えます。
-
バックエンドサーバが返すSet-Cookieヘッダのパス名が/abc/の場合
Set-Cookieヘッダのパス名が,ProxyPassディレクティブの転送先URLのパス名部分に前方から一致する場合は,Set-Cookieヘッダのパス名としてProxyPassディレクティブのパス名で置き換えます。
-
バックエンドサーバが返すSet-Cookieヘッダのパス名が/abc/xxx/の場合
ProxyPassディレクティブの転送先URLのパス名部分とSet-Cookieヘッダのパス名が一致しない場合は,リバースプロキシでのSet-Cookieヘッダ変換は実行しません。バックエンドサーバが応答したSet-Cookieヘッダをそのままクライアントに返します。
-
(5) 性能に関する注意事項
-
ProxyPassディレクティブにドメイン名またはホスト名を指定している場合,DNSへの問い合わせが発生します。バックエンドサーバのIPアドレスがわかっている場合は,hostsファイルにあらかじめIPアドレスを記載しておくことによって,名前解決の時間を短縮できます。
-
バックエンドサーバとの最大コネクション数は次の計算式で表されます。
バックエンドサーバがCosminexusのNIO HTTPサーバの場合,バックエンドサーバとの最大コネクション数以上の値をwebserver.connector.nio_http.max_connectionsキーに設定してください。
- Windowsの場合
最大コネクション数=(ThreadsPerChildディレクティブ値 + H2MaxWorkersディレクティブ値※1) ×ProxyPassディレクティブの定義数※2
- UNIXの場合
最大コネクション数=(MaxClientsディレクティブ値 + H2MaxWorkersディレクティブ値※1 × ServerLimitディレクティブ値) ×ProxyPassディレクティブの定義数※2
- 注※1
-
HTTP/2通信を使用しない場合は0とする。
- 注※2
-
ほかのProxyPassと設定を共有しているものは除く。