REMOTE_ADDRをプロキシ先サーバーにも保持させるには?
- 2015.08.20
- Apache 開発環境/開発ツール
- demo
リバースプロキシサーバーを経由してオリジンサーバーに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上にて公開されています。
- https://github.com/gnif/mod_rpaf
- https://github.com/y-ken/mod_rpaf
- https://github.com/ttkzw/mod_rpaf-0.6
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」にしておきます。
ずいぶん複雑な設定にはなりますが、追加モジュールをインストールできない場合には利用してみてください。
参考
- http://heartbeats.jp/hbblog/2012/03/mod-rpaf.html
- http://hb.matsumoto-r.jp/entry/2014/09/01/033038
- http://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
- http://digiclu.hatenablog.com/entry/2012/04/05/231151
関連記事: