リバースプロキシ
リバースプロキシ

○環境 (Debian etch)

静的コンテンツ(html,css,image,jsファイル等) は Apache 2.2 で 処理。
動的コンテンツ(CGI、Perl) は バックエンドのApache 1.3 + mod_perl で処理を行い、動作を高速化。

こんな感じの環境を構築しているのですが、mod_perlで動作しているプログラム中でIPアドレスとか取得すると、
当然というかlocalhostになってしまいます。

ブラウザ(外部アクセス) ← → Apache 2.2(gw) ← (☆) → Apache 1.3 (Backend/mod_perl)

ここ(☆印)のアクセスがApache1.3のアクセスログに記録される

そこで、実際の外部からのアクセスのあったIPアドレスを取得するにはProxy変数 X-Forwarded-For から取得するのですが、
プログラムの規模が大きいと書き換えるのも大変なのでサーバの設定で対応するといいみたいです。

mod_rewrite とか mod_proxy とか

/etc/apache2/sites-available/xxxxxxx


    ServerName example.com
    ServerAdmin webmaster@example.com
      :
      :
    ProxyPass /hoge/hogege/ http://example.com:8443/hoge/hogege/
    ProxyPassReverse /hoge/hogege/ http://example.com:8443/hoge/hogege/

見たいな感じにして、普段はApache2.2が実行、但し、CGIが実行される部分だけApache1.3に渡している感じです。
ここら辺は詳しくは参考にしたサイト
http://webos-goodies.jp/archives/51261261.html
http://dev.ariel-networks.com/Members/inoue/rewrite-and-redirect
http://www.clip.gr.jp/~imai/PukiImaiWiki/index.php?Apache%2F%A5%EA%A5%D0%A1%BC%A5%B9%A5%D7%A5%ED%A5%AD%A5%B7
あたりを見てみるといいと思います。

で問題のIPアドレスとかに関してですが、
やってることはApache 2.2 -> Apache 1.3 のアクセス時に X-Forwarded-For の値をremote_ip に上書きするだけ。

/etc/apache/startup.pl に以下を追加する。

# IP rewrite
use Apache::Constants qw(OK);
sub My::RewriteRemoteAddr ($) {
    my $r = shift;
    if (my ($ip) = $r->header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
          $r->connection->remote_ip($ip);
        }
    if (my ($host) = $r->header_in('X-Forwarded-Host') =~ /([^,\s]+)$/) {
          $r->connection->remote_host($host);
    }
    return OK;
}

Apacheの設定を変更する。
PerlHeaderParserHandler というのが追加したところ。

/etc/apache/conf.d/0x_xxxxx.conf

    
      
        Alias /foo /var/www/hoge/hogege
      
      
        AllowOverride All
        Order allow,deny
        Allow from all
        SetHandler perl-script
        #PerlHandler Apache::PerlRun
        PerlHandler Apache::Registry
        PerlInitHandler Apache::StatINC
        PerlSendHeader On
        PerlHeaderParserHandler My::RewriteRemoteAddr
        Options +ExecCGI
      
    

Apache1.3のアクセスログにも実際のIPアドレスを記録したい場合は、以下のようにするといいみたい。

/etc/apache/httpd.conf

#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{forensic-id}n\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{forensic-id}n\"" combined

※ 以下のページを参考にさせていただきました。
http://webos-goodies.jp/archives/51261261.html
http://dev.ariel-networks.com/Members/inoue/rewrite-and-redirect
http://www.clip.gr.jp/~imai/PukiImaiWiki/index.php?Apache%2F%A5%EA%A5%D0%A1%BC%A5%B9%A5%D7%A5%ED%A5%AD%A5%B7

http://www.hozen.org/ml/1/thread/603
http://develooper.com/code/mpaf/mod_proxy_add_forward.c

http://blog.bbtune.com/items/0000986.html
http://d.hatena.ne.jp/tokuhirom/20060323/1143087831

※ mod_rpafというのもあるそうです。
X-Forwarded-Forに関してはやってることが同じっぽいですが、使える環境ならそちらの方がスマートかも。
http://www.drk7.jp/MT/archives/000573.html
http://module.jp/blog/various_pool.html