mod_proxy
Apache module mod_proxy
説明: マルチプロトコル プロキシ/ゲートウェイサーバ
ソースファイル: mod_proxy.c
概要
table:警告
とってもインターネットにとっても危険です。
mod_proxyおよび関連モジュールは Apache HTTP Serverのプロキシ/ゲートウェイ機能を実装し、複数の異なる負荷分散(load balancing)アルゴリズムの一般的なプロトコルをサポートします。サードパーティーのモジュールは追加のプロトコルと負荷分散アルゴリズムのサポートを追加できます。
必要な機能を提供するには、一連のモジュールをサーバーに読み込む必要があります。これらのモジュールは、ビルド時に静的に組み込むことも、LoadModule ディレクティブを使用して動的に組み込むこともできます。セットには次のものを含める必要があります:
mod_proxy 基本的なプロキシ機能を提供する
mod_proxy_balancer と 1 つ以上のバランサー モジュール 負荷分散が必要な場合。(詳細については、mod_proxy_balancer を参照してください。)
1 つ以上のプロキシ スキームまたはプロトコル モジュール:
table:module
プロトコル モジュール
さらに、拡張機能は他のモジュールによって提供されます。キャッシュは mod_cache および関連モジュールによって提供されます。SSL/TLS プロトコルを使用してリモート サーバーに接続する機能は、mod_ssl の SSLProxy* ディレクティブによって提供されます。これらの機能を利用するには、これらの追加モジュールをロードして構成する必要があります。 フォワードプロキシとリバースプロキシ/ゲートウェイ
Apache HTTP Server は、フォワード プロキシ モードとリバース プロキシ モード (ゲートウェイとも呼ばれる) の両方で構成できます。
通常のフォワード プロキシは、クライアントとオリジン サーバーの間にある中間サーバーです。オリジン サーバーからコンテンツを取得するには、クライアントは、ターゲットとしてオリジン サーバーを指定してプロキシに要求を送信します。次に、プロキシはオリジン サーバーにコンテンツを要求し、それをクライアントに返します。クライアントは、フォワード プロキシを使用して他のサイトにアクセスするように特別に構成する必要があります。
フォワード プロキシの一般的な使用法は、ファイアウォールによって制限されている内部クライアントにインターネット アクセスを提供することです。フォワード プロキシは、ネットワーク使用量を削減するためにキャッシュ (mod_cache によって提供される) を使用することもできます。 フォワード プロキシは、ProxyRequests ディレクティブを使用してアクティブ化されます。フォワード プロキシを使用すると、クライアントはサーバーを介して任意のサイトにアクセスし、実際のオリジンを隠すことができるため、フォワード プロキシをアクティブ化する前に、承認されたクライアントだけがプロキシにアクセスできるようにサーバーを保護することが重要です。 これとは対照的に、リバース プロキシ (またはゲートウェイ) は、クライアントにとって通常の Web サーバーとまったく同じように見えます。クライアント側で特別な設定は必要ありません。クライアントは、リバース プロキシの名前空間内のコンテンツに対して通常の要求を行います。次に、リバース プロキシはそれらの要求の送信先を決定し、コンテンツがそれ自体の発信元であるかのように返します。
リバース プロキシの一般的な使用法は、インターネット ユーザーにファイアウォールの背後にあるサーバーへのアクセスを提供することです。リバース プロキシは、複数のバックエンド サーバー間で負荷を分散したり、低速のバックエンド サーバーにキャッシュを提供したりするためにも使用できます。さらに、リバース プロキシは、複数のサーバーを同じ URL 空間に持ち込むためにも使用できます。
基本サンプル
以下の例は、開始する上で役立つ非常に基本的なアイデアにすぎません。個々のディレクティブに関するドキュメントをお読みください。
さらに、キャッシュを有効にしたい場合は、mod_cache のドキュメントを参照してください。 code:Reverse Proxy
code:Forward Proxy
ProxyRequests On
ProxyVia On
<Proxy "*">
Require host internal.example.com
</Proxy>
code:Websocket Upgrade (2.4.47以降)
Handler経由のアクセス
ハンドラー経由のアクセス
適切なハンドラー パススルーを作成することで、リクエストをリバース プロキシ リクエストとして処理するように強制することもできます。以下の構成例では、リバース プロキシを使用して、PHP スクリプトのすべてのリクエストを指定された FastCGI サーバーに渡します。
code:リバース プロキシ PHP スクリプト
<FilesMatch "\.php$">
# Unix socket には 2.4.7 以降が必要です
SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/"
</FilesMatch>
この機能は、Apache HTTP Server 2.4.10 以降で使用できます。
Workers
プロキシは、ワーカーと呼ばれるオブジェクトでオリジン サーバーの構成と通信パラメータを管理します。組み込みワーカーには、デフォルトのフォワード プロキシ ワーカーとデフォルトのリバース プロキシ ワーカーの 2 つがあります。追加のワーカーは明示的に構成できます。
2 つのデフォルトのワーカーは固定構成で、リクエストに一致するワーカーが他にない場合に使用されます。HTTP Keep-Aliveや接続の再利用は使用されません。代わりに、オリジン サーバーへの TCP 接続はリクエストごとに開かれ、閉じられます。
code:example
これにより、指定されたタイムアウト値を使用するオリジン サーバーの URL http://backend.example.com に関連付けられたワーカーが作成されます。フォワード プロキシで使用する場合、ワーカーは通常、ProxySet ディレクティブによって定義されます。 code:example
または、Proxy と ProxySet を使用することもできます。
code:example
ProxySet connectiontimeout=5 timeout=30
</Proxy>
明示的に構成されたワーカーを転送モードで使用することはあまり一般的ではありません。これは、転送プロキシが通常、さまざまなオリジン サーバーと通信するためです。一部のオリジン サーバーに明示的にワーカーを作成すると、頻繁に使用される場合は便利です。明示的に構成されたワーカーには、転送プロキシやリバース プロキシの概念はありません。これらは、オリジン サーバーとの通信の共通概念をカプセル化します。リバース プロキシで使用するために ProxyPass によって作成されたワーカーは、オリジン サーバーの URL がワーカー URL と一致する場合は常に転送プロキシ リクエストにも使用され、その逆も同様です。
直接ワーカーを識別する URL は、指定されたパス コンポーネントを含むオリジン サーバーの URL です。
code:example
この例では、それぞれ別の接続プールと構成を使用する 2 つの異なるワーカーを定義します。
ワーカー共有
ワーカー共有は、ワーカー URL が重複している場合に発生します。これは、一部のワーカーの URL が、構成ファイルで後で定義されている別のワーカーの URL の先頭部分文字列である場合に発生します。次の例では、
code:example
2 番目のワーカーは実際には作成されません。代わりに、最初のワーカーが使用されます。利点は、接続プールが 1 つしかないため、接続がより頻繁に再利用されることです。後のワーカーに明示的に指定されたすべての構成属性は無視されることに注意してください。これは警告としてログに記録されます。上記の例では、URL /examples の結果のタイムアウト値は 10 ではなく 60 になります。
ワーカー共有を回避する場合は、ワーカー定義を URL の長さで並べ替えます。最も長いワーカー URL から始めます。ワーカー共有を最大化する場合は、逆の並べ替え順序を使用します。 ProxyPass ディレクティブの順序に関する関連する警告も参照してください。
明示的に構成されたワーカーには、直接ワーカーと (ロード) バランサ ワーカーの 2 種類があります。これらは、ProxyPass ディレクティブで後述する多くの重要な構成属性をサポートしています。同じ属性は、ProxySet を使用して設定することもできます。 直接ワーカーに使用できるオプションのセットは、オリジン サーバーの URL で指定されるプロトコルによって異なります。使用可能なプロトコルには、ajp、fcgi、ftp、http、scgi などがあります。
バランサ ワーカーは、メンバーと呼ばれる直接ワーカーを使用して実際にリクエストを処理する仮想ワーカーです。各バランサには複数のメンバーを含めることができます。バランサはリクエストを処理するときに、構成されたロード バランシング アルゴリズムに基づいてメンバーを選択します。
バランサ ワーカーは、そのワーカー URL がプロトコル スキームとしてバランサを使用する場合に作成されます。バランサ URL は、バランサ ワーカーを一意に識別します。メンバーは、BalancerMember を使用してバランサに追加されます。 オリジン ドメインの DNS 解決
DNS 解決は、オリジン ドメインへのソケットが初めて作成されたときに行われます。接続の再利用が有効になっている場合、各バックエンド ドメインは子プロセスごとに 1 回だけ解決され、子がリサイクルされるまで、それ以降のすべての接続用にキャッシュされます。バックエンド ドメインを含む DNS メンテナンス タスクを計画する際には、この情報を考慮する必要があります。接続の再利用の詳細については、ProxyPass パラメータも確認してください。
プロキシへのアクセスを制御する
次の例のように、<Proxy> コントロール ブロックを使用して、プロキシにアクセスできるユーザーを制御できます。
code:example
<Proxy "*">
Require ip 192.168.0
</Proxy>
フォワード プロキシ (ProxyRequests ディレクティブを使用) を使用している場合は、アクセスを厳密に制限することが重要です。そうしないと、サーバーは、任意のクライアントが自分の本当の ID を隠したまま任意のホストにアクセスするために使用できます。これは、ネットワークとインターネット全体の両方にとって危険です。リバース プロキシ (ProxyRequests Off で ProxyPass ディレクティブを使用) を使用する場合は、クライアントは明示的に設定したホストにしかアクセスできないため、アクセス制御はそれほど重要ではありません。 起動が遅い Slow Startup
ProxyBlock ディレクティブを使用している場合、ホスト名の IP アドレスは起動時に検索され、後で一致テストを行うためにキャッシュされます。ホスト名の検索の速度によっては、数秒 (またはそれ以上) かかる場合があります。
イントラネット プロキシ
イントラネットにある Apache httpd プロキシ サーバーは、外部の要求を会社のファイアウォール経由で転送する必要があります (このためには、ProxyRemote ディレクティブを設定して、それぞれのスキームをファイアウォール プロキシに転送します)。ただし、イントラネット内のリソースにアクセスする必要がある場合は、ホストにアクセスするときにファイアウォールをバイパスできます。NoProxy ディレクティブは、イントラネットに属し、直接アクセスする必要があるホストを指定する場合に便利です。 イントラネット内のユーザーは、WWW 要求からローカル ドメイン名を省略する傾向があり、http://somehost.example.com/ ではなく "http://somehost/" を要求します。一部の商用プロキシ サーバーでは、このような操作を回避し、構成されたローカル ドメインを暗示して要求を処理するだけです。ProxyDomain ディレクティブが使用され、サーバーがプロキシ サービス用に構成されている場合、Apache httpd はリダイレクト応答を返し、クライアントを正しい完全修飾サーバー アドレスに送信できます。ユーザーのブックマーク ファイルに完全修飾ホストが含まれるため、これが推奨される方法です。 プロトコルの調整
mod_proxy が、キープアライブまたは HTTP/1.1 を適切に実装していないオリジン サーバーにリクエストを送信する場合、リクエストでキープアライブなしの HTTP/1.0 を使用するように強制できる環境変数が 2 つあります。これらは、SetEnv ディレクティブで設定されます。 これらは、force-proxy-request-1.0 および proxy-nokeepalive ノートです。
code:example
<Location "/buggyappserver/">
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</Location>
2.4.26 以降では、"no-proxy" 環境変数を設定して、現在のリクエストを処理する mod_proxy を無効にすることができます。SetEnv は十分に早く評価されないため、この変数は SetEnvIf で設定する必要があります。 リクエスト本文
POST などの一部のリクエスト メソッドには、リクエスト本文が含まれます。HTTP プロトコルでは、本文を含むリクエストは、チャンク転送エンコーディングを使用するか、Content-Length リクエスト ヘッダーを送信する必要があります。これらのリクエストをオリジン サーバーに渡すとき、mod_proxy_http は常に Content-Length を送信しようとします。ただし、本文が大きく、元のリクエストでチャンク エンコーディングが使用されていた場合は、アップストリーム リクエストでもチャンク エンコーディングが使用されることがあります。この選択は、環境変数を使用して制御できます。proxy-sendcl を設定すると、常に Content-Length が送信されるため、アップストリーム サーバーとの互換性が最大限に確保されます。一方、proxy-sendchunked を設定すると、チャンク エンコーディングを使用することでリソースの使用が最小限に抑えられます。 状況によっては、サーバーは、リクエスト本文の要求された処理を満たすために、リクエスト本文をディスクにスプールする必要があります。たとえば、元の本文がチャンク エンコーディングで送信され (サイズが大きい)、管理者がバックエンド リクエストを Content-Length または HTTP/1.0 で送信するように要求している場合、このスプールが発生します。このスプールは、リクエスト本文にすでに Content-Length ヘッダーが含まれているが、サーバーが受信リクエスト本文をフィルターするように構成されている場合にも発生する可能性があります。