Apacheでリバースプロキシを設定する方法

Apacheは、拡張機能を介したものも含め、サポート機能をフルに提供する多用途のWebサーバーです。この記事では、mod_proxyモジュールを使用して、Apacheをリバースプロキシの役割で構成します。

Apacheは、リバースプロキシとしての第一候補ではないかもしれませんが、NGINXのようなより最新の代替手段が注目を集める傾向にあるため、mod_proxyはすでにApacheを実行しており、トラフィックを別のサービスにルーティングする必要があるサーバーに役立ちます。特定のドメインに対するリクエストを別のWebサーバーに渡すために、Apache仮想ホストを設定できます。

このガイドでは、DebianベースのシステムでApache 2.4を使用しています。また、トラフィックをプロキシするサーバーが、Apacheホストからすでにネットワークでアクセス可能であると想定します。この記事では、一意の仮想ホストに基づいてプロキシを有効にすることに重点を置いていますが、mod_proxyは、Apacheサーバーの構成の一部として、または.htaccessファイルを経由してディレクトリレベルでグローバルに構成することもできます。

プロキシモジュールの有効化

mod_proxyは、デフォルトのApacheインストールに含まれています。a2enmodを使用して、モジュールとその独立したHTTPコンポーネントを今すぐアクティブにします:

sudo a2enmod proxy

sudo a2enmod proxy_http

これにより、Apacheは他のホストへのHTTP接続のプロキシをサポートするように設定されます。このモジュールは、Apache構成ファイルのProxy接頭辞の指示を使用して構成されます。次にこれらを設定します。

プロキシされた仮想ホストの設定

example.comを内部IPアドレス192.168.0.1に転送する仮想ホストを設定しましょう。Apacheホストを指すexample.comのDNSレコードを追加する必要があります。

このシナリオでのプロキシにより、訪問者は外部アドレスを介して内部Webサーバーに透過的にアクセスできます。Apacheは、トラフィックを最終目的地にルーティングするゲートキーパーとして機能します。ユーザーにはexample.comが表示されますが、実際にはApacheは別のサーバーを介してリクエストを解決します。

/etc/apache2/sites-available内に次のコンテンツを使用して新しい仮想ホストファイルを追加します:

ServerName example.com
ProxyPass / http://192.168.0.1/ nocanon
ProxyPassReverse / http://192.168.0.1/

ProxyPassProxyPassReverseディレクティブは、example.comへのトラフィックを192.168.0.1にプロキシする必要があることを指定します。オプションのnocanonキーワードは、Apacheに生のURLをリモートサーバーに渡すように指示します。このキーワードがないと、Apacheは自動的にURLを正規化します。これは、一部のサーバーやフレームワークと互換性がない場合があります。nocanonを使用すると互換性が保証されますが、URLベースのプロキシ攻撃に対するApacheの組み込み保護が無効になるため、セキュリティ体制に影響を与える可能性があります。

ProxyPassReverseは、構成をリバースプロキシ設定として区別するために提供する必要があります。Apacheは、提供されたURLを使用して、バックエンドによって発行されたLocationContent-Location、およびURI応答ヘッダーを書き換えます。これにより、後続のリクエストは内部サーバーに直接到達しようとするのではなく、引き続きリバースプロキシにヒットします。

この構成により、すべてのリクエストがプロキシされます。ProxyPassProxyPassReverseの指示を調整することで、プロキシを/mediaなどの特定のパスに制限できます:

ProxyPass /media http://192.168.0.1/
ProxyPassReverse /media http://192.168.0.1/

複数のProxyPassルールを追加すると、1つの仮想ホストを使用して複数のターゲット間でリクエストをルーティングできます。ルールは、記述された順序で照合されます。より複雑なルーティング動作が必要な場合は、代わりにProxyPassMatchディレクティブを使用します。これはProxyPassと同等ですが、受信URLを正規表現と照合します:

ProxyPassMatch ^/client/(.*)/images$ http://192.168.0.1/

仮想ホストファイルを保存し、a2ensiteコマンドを使用して有効にします。これにより、sites-availableディレクトリを基準としたファイルのベース名が取得されます:

sudo a2ensite example-proxy-vhost

Apacheを再起動して変更を適用します:

sudo service apache2 restart

これで、シンプルなプロキシが動作するはずです。example.comにアクセスしてみてください。192.168.0.1によって提供されるコンテンツが表示されます。リクエストはApacheホストで終了し、その後内部サーバーにプロキシされます。

SSLの使用

上記の例では、SSLは省略されています。実稼働のワークロードでは、仮想ホストにSSLCertificateFileSSLCertificateKeyFileの設定を追加してこれを設定する必要があります。これらは、SSL接続を検証するときに使用するSSL証明書と鍵を指定します。Let's Encryptのcertbotを使用してセットアップを自動化することもできます。

このようにSSLを構成すると、Apacheホストでセキュアな接続が終了します。Apacheとプロキシターゲット間の接続は、プレーンHTTPを介して行われます。

プロキシ接続のセキュリティも確保する必要がある場合は、mod_sslで提供されるSSLProxyオプションを使用する必要があります。Apacheとプロキシターゲットサーバーの両方が同じ証明書にアクセスできる場合、SSLProxyEngine = Onが最も基本的な構成として機能します。このオプションは、プロキシ接続を介してSSL情報をフィードするように指示します。

プロキシオプション

Apacheリバースプロキシには、転送動作を調整するために使用できるいくつかのオプションディレクティブがあります。一般的に使用されるオプションをいくつか紹介します:

  • ProxyAddHeaders- Apacheは、デフォルトでX-Forwarded-HostXForwarded-For、およびX-Forwarded-Serverヘッダーをバックエンドサーバーに渡します。これらのヘッダーにより、バックエンドはApacheを介してリクエストがプロキシされたことを識別できます。このヘッダーをOffに設定すると、Apacheはこれらのヘッダーを追加しなくなります。
  • ProxyErrorOverride- Apacheは、指示されない限り、バックエンドサーバーから送信された応答を妨害しません。バックエンドが400、404、500、またはその他のエラーコードを提供する場合、ユーザーはそのコンテンツをそのまま受け取ります。ProxyErrorOverrideを設定すると、この動作が変わり、Apacheがエラーページのコンテンツを構成されたErrorDocumentに置き換えるようになります。これは、すべてのバックエンドからのエラーを、プロキシホストで一元化された構成で一様に処理したい場合に望ましい場合があります。
  • ProxyPassReverseCookieDomain- これは、リバースプロキシに必須のProxyPassReverseディレクティブと同様に機能します。Set-Cookieヘッダーのドメインを書き換えて、バックエンドサーバーのホスト名ではなく、仮想ホストの名前を参照します。
  • ProxyPreserveHost- Apacheは通常、独自のホスト名をHostヘッダーの値としてバックエンドサーバーに送信します。このディレクティブを設定すると、代わりに元のHostヘッダーが送信されます。これは、バックエンドソフトウェアが独自のホスト名ベースのルーティングを実行する場合に必要になる場合があります。
  • ProxyTimeout- このディレクティブを使用して、バックエンドサーバーがプロキシされたリクエストを処理している間にApacheが待機する時間を調整します。タイムアウトを超過すると、Apacheはリクエストを中止し、クライアントにエラーコードを返します。これは、サーバーレベルのTimeout値がデフォルトです。

これらのディレクティブは、仮想ホストファイルの追加行として設定できます。変更を適用するたびにApacheサービスを再起動することを忘れないでください。

ロードバランシング

Apacheのリバースプロキシの実装は、複数の異なるバックエンド間のロードバランシングもサポートしています。これにより、example.comへのリクエストが、バランシングプール内のいずれかのサーバーにヒットします。

BalancerMember http://192.168.0.1
BalancerMember http://192.168.0.2
ProxySet lbmethod=bytraffic

ProxyPass / balancer://example-balancer
ProxyPassReverse / balancer://example-balancer

この例では、example-balancerプールの2つのサーバーのいずれかにリクエストがルーティングされます。ロードバランシングアルゴリズムはlbmethod設定によって定義されます。ここで使用されているbytraffic値は、各サーバーが同じ量のトラフィックを処理できるようにします。

代替のbyrequestsバランシングメソッドは、bytrafficのよりシンプルなバージョンであり、各バックエンドに受信リクエストを均等に割り当てます。bybusynessバランサーは、各バックエンドが処理しているリクエストの数を追跡し、新しいリクエストを最も「ビジーでない」バックエンドに割り当てます。

まとめ

mod_proxyモジュールは、Apacheをリバースプロキシホストに変換し、名前ベースのルーティングを使用して複数の独立したサービスにアクセスできるようにします。ロードバランシングを追加して、サーバーフリート全体にリクエストを分散することにより、安定性と稼働時間を確保することもできます。

他にもプロキシフレーバーを利用できます。mod_proxyと一緒に追加のアドオンをインストールすることで、FTP、WebSocket、HTTP2接続などをプロキシできます。モジュールの完全なリストはApacheのドキュメントでご覧いただけます。