ぱそくま ろご
Linux > Apache HTTP > リバースプロキシ

リバースプロキシ

リバースプロキシとは

プロキシサーバー(フォワードプロキシ)はクライアントからのリクエストを代行してサーバーにリクエストします。 リバースプロキシとはこれとは逆にサーバー側にきたリクエストを別のサーバーに全て中継します。 用途としては1つのIPアドレスで複数のドメインを運用するときなどに使います。 もちろん、この場合virtualhostでも運用が可能ですが、サーバー処理を分散させる場合などはこの構成のほうがよいでしょう。

リバースプロキシの構成例

下表のような構成の場合、下図のようになります。

リバースプロキシ グローバルIP:XXX.XXX.XXX.XXX
ローカルIP:192.168.4.1
ドメイン:www.hoge.comとwww.hoge2.comの2つ
Webサーバー1
(バックエンドサーバー1)
ローカルIP:192.168.5.1
処理するドメイン:www.hoge.com
Webサーバー2
(バックエンドサーバー1)
ローカルIP:192.168.5.2
処理するドメイン:www.hoge2.com
リバースプロキシの例

必要なモジュール

リバースプロキシをhttpdで実装するには以下のモジュールが必要となります。

リバースプロキシに必要なモジュール

  • #proxy機能のベース
  • LoadModule proxy_module modules/mod_proxy.so
  • #httpリクエストに必要
  • LoadModule proxy_http_module modules/mod_proxy_http.so


リバースプロキシの設定

ProxyPassディレクティブで代行するパスと代行先のWEBサーバーを関連付けます。イメージ的にはサーバーのパスを別のサーバーのパスに置換する感じです。

リーバースプロキシの設定例1

  • <VirtualHost *:80>
  •   ServerName hoge.com
  •   ServerAlias *.hoge.com
  •   ProxyPass / http://192.168.5.1/
  •   ProxyPassReverse / http://192.168.5.1
  • </VirtualHost>

注意点1 - バックエンドでのvirtualhostの運用

バックエンドのWEBサーバー(上図だと192.168.5.1や2)が処理するHTTP-HOST(自身のホスト名)はProxyPassで指定したものになるので、 ServerNameによるVirtualHostの運用ができなくなります。 (例えばwww.hoge.com, www1.hoge.comそれぞれ別のページを表示したくても、ServerNameが全て192.168.5.1となってしまうので名前による運用ができない。) これを解決するにはProxyPreserveHost Onの設定が必要となります。

<VirtualHost *:80>
  ServerName hoge.com
  ServerAlias *.hoge.com
  ProxyPreserveHost On
  ProxyPass / http://192.168.5.1/

</VirtualHost>

ProxyPreserveHostディレクティブをOnに設定することにより、"HTTP-HOST"が"HTTP-X-FORWARDED-HOST"に書き換わります。

注意点2 - リモートIP

バックエンドのWEBサーバー(上図だと192.168.5.1や2)が取得するリモートIPはクライアントのIPではなくリバースプロキシサーバーのIP(上図だと192.168.4.1)となります。 (ProxyPreserveHostディレクティブをOnに設定してもリモートIPは変わりません。もちろん、delegate等のプロキシーソフトも同様です。) よって、以下の問題が生じます。

  • 本来のリモートIP(クライアントのIP)が取得できないので正常なアクセスログが取得できない。
  • リモートIPが全てリバースプロキシサーバーのIPのため、「Allow from 192.168.XXX.」のようなアクセス制限が意味をなさない。

ここ問題を解決してくれるのがmod_extract_forwardedです。このモジュールはリモートIPを"X-Forwarded-For"のIPアドレスに書き換えてくれます。平たく言うと、リモートIPを本来のクライアントのIPアドレスに書き換えてくれます。 これはバックエンドのWebサーバーにインストールしてください。 なお、このモジュールはソースでしか公開されていなので、apxsを使ったコンパイルが必要です。apxsがインストールされていない場合は「Apache HTTPの基礎」の「httpdのインストール」を参考にしてください。

mod_extract_forwardedのインストール

mod_extract_forwardedのインストールは以下の通りです。必要なモジュールのダウンロード方法も書いてあります。 (参考:mod_rpaf のかわりに mod_extract_forwarded...)

mod_extract_forwardedの導入方法

  1. mod_extract_forwardedのサイトに行き「Download the source」をクリックし、mod_extract_forwardedのソースをダウンロード。
  2. mod_extract_forwardedのパッチmod_extract_forwarded.patchをダウンロード。
  3. 以下を参考に、解凍、パッチ、インストールします。
    • # tar zxf extract_forwarded-2.0.2.tar.gz
    • # cd extract_forwarded
    • # patch < ../mod_extract_forwarded.patch
    • miss...
    • .
    • # apxs -i -c -a mod_extract_forwarded.c
  4. mod_extract_forwardedの設定をhttpd.confに記入します。
    # The following modules are not loaded by default:
    #
    #LoadModule cern_meta_module modules/mod_cern_meta.so
    #LoadModule asis_module modules/mod_asis.so
    LoadModule extract_forwarded_module /usr/lib/httpd/modules/mod_extract_forwarded.so
    .
    .
    .
    DocumentRoot "/var/www/html"
     
    MEForder refuse,accept #refuse,acceptの順
    MEFrefuse all #全て拒絶
    MEFaccept 192.168.4.1 #リバースプロキシサーバーのIP
    

    ちなみに青字部分はapxsが正常に終了すると自動で書かれるはずですが、ない場合は記入してください。

リバースプロキシがつながらない場合

ロードバランサーを使用している場合やtomcatへ転送したい場合など、503エラー(server temporarily unavailable)が表示されることがあります。 これはTCP(ポート番号を使うなど)を使った転送になるため、SELinuxが有効の場合デフォルトでは許可され待ていません。 よって、許可する場合は以下のようにhttpd_can_network_connectを有効にする必要があります。

Tomcatなどへの接続を有効にするサンプル

[root ~]setsebool -P httpd_can_network_connect