Apacheでリバースプロキシする際にリモートIPアドレスを保持するには?

リバースプロキシサーバーを経由してオリジンサーバーにHTTP接続する環境では、接続先サーバーにブラウザのIPアドレスが記録されません。そのため、アクセスログ解析ができなかったり、IPアドレスベースの認証ができないといった問題があります。

ジーンコードなどWebサイト変換製品もリバースプロキシ型なので、同様の問い合わせを受けたりします。

この問題に対処する方法を3つ紹介します。

mod_rpafを使用する

リバースプロキシを経由してオリジンサーバーにアクセスした際、リモートIPアドレスがリバースプロキシのIPアドレスに変更されてしまう問題を解決するための専用モジュールがmod_rpafです。リバースプロキシではなく、接続先のオリジンサーバーにApacheモジュールをインストールします。

mod_rpafの良い点は、Apacheの内部変数であるリモートIPアドレスを直接変更するので、透過的であることです。このモジュールを導入するだけで、アクセスログに出力されるリモートIPアドレスやIPアドレスベースの認証などがリバースプロキシを経由していない時と同じように動作します。

mod_rpafはサードパーティー製モジュールのため、標準のApacheには付属していませんが、ソースコードが公開されており、ビルドすることでインストールできます。

ただし、残念ながらmod_rpafは元々の制作者によるメンテナンスはされておらず、Webサイトもなくなってしまいました。現在は、有志によってフォークされた何種類かのmod_rpafがGitHub上にて公開されています。

mod_remoteipを使用する

Apache 2.4からは、mod_remoteipというモジュールが標準モジュールとして提供され、リモートIPアドレスの問題解決がされています。

しかしながら、リモートIPアドレスはプロキシ前のIPアドレスに置き換わるものの、リモートホスト名が置き換えられないため、ホスト名でのアクセス認証ができなかったり、アクセスログのリモートホスト名部分も置き換わらなかったりします。mod_remoteipという名前の通り、リモートIPアドレスしか対応していないようですね。

なお、GitHubにはApache 2.2版のmod_remoteipがあるので、Apache 2.2でも使うことができます。

https://github.com/ttkzw/mod_remoteip-httpd22

専用モジュールは使わずに設定する

専用モジュールを使わずに実現する方法もあります。

 ■リバースプロキシの設定

まず、リバースプロキシ側はmod_rewriteとmod_headersを有効にしておきます。rewriteでリモートIPアドレスとリモートホスト名を環境変数に設定して、RequestHeaderディレクティブで環境変数の値をリクエストヘッダに設定します。rewriteを使っている関係上、Proxyもrewriteで行うところがポイントです(ProxyPassディレクティブは使えません)。


RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^(.*)$
RewriteRule . - [env=remoteaddr:%1]
RewriteCond %{REMOTE_HOST} ^(.*)$
RewriteRule . - [env=remotehost:%1]

RequestHeader set X-Remote-Addr %{remoteaddr}e
RequestHeader set X-Remote-Host %{remotehost}e

RewriteRule ^/(.*)$ http://192.168.1.10/%1 [P,L]

 ■オリジンサーバーの設定

Proxy接続先となるオリジンサーバー側は、リクエストヘッダに渡されたリモートIPアドレス・ホスト名を見て、アクセス制御・ログ出力を行います。同じく、mod_rewriteを駆使してヘッダの取得やアクセス拒否を行っています。


RewriteEngine On

RewriteCond %{REMOTE_ADDR} ^(.*)$
RewriteRule . - [env=remoteaddr:%1]
RewriteCond %{HTTP:X-Remote-Addr} ^(.+)$
RewriteRule . - [env=remoteaddr:%1]

RewriteCond %{REMOTE_HOST} ^(.*)$
RewriteRule . - [env=remotehost:%1]
RewriteCond %{HTTP:X-Remote-Host} ^(.+)$
RewriteRule . - [env=remotehost:%1]

RewriteCond %{ENV:remoteaddr} ^172\.16\.0\.10$
RewriteRule . - [F,L]
RewriteCond %{ENV:remotehost} \.example\.com$
RewriteRule . - [F,L]

LogFormat "%{remotehost}e %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

なお、リモートホスト名を使用する際は、プロキシサーバー側で「HostnameLookups On」にしておきます。

ずいぶん複雑な設定にはなりますが、追加モジュールをインストールできない場合には利用してみてください。

参考