Reverse Proxy経由でlighttpdへアクセスした際、リモートIPを取得する方法

lighttpd


リバースプロキシ導入の際に、バックエンドサーバーで取得するリモートIPアドレスが全てリバースプロキシのIPアドレスになってしまうという問題。


これについては、

http://www.namazu.org/~takesako/diary/?date=20031205

で紹介されている通り、バックエンドのWebサーバが"Apache"の場合は「mod_rpaf」を使えば良いし、このやり方についてはインターネット上で結構紹介されている。


では、バックエンドのWebサーバが"lighttpd"の場合は、どうすればよいのかというのが今日のお話。


さて、この問題の対策については、

http://www.mylab.jp/diary/20031203.html#p01

で紹介されている通り、

X-Forwarded-For というアクセス元の IP をログに記録すればよい

なのだが、そうはいってもApacheのようにモジュールの組み込みでスマートに解決したい。


この件については、探し方がまずかったのか、今日の時点ではGoogle先生に聞いても、なかなか情報が見つからず、仕方が無いのでlighttpdのドキュメントを読み漁ることにした。


・・・あるじゃないですか。それっぽいのが。


http://trac.lighttpd.net/trac/wiki/Docs


ここのモジュール一覧の中にある「mod_extforward」ですね。


http://trac.lighttpd.net/trac/wiki/Docs/ModExtForward


早速、このドキュメントに書いてある通りインストールを行ったのですが、
これまた環境依存なのか、すんなりインストールできなかった


結論から言うと、インストールできて(無理矢理?)、いい感じで動作したので、そのやり方をここに書き留めておく。
以下、作業ログ。(lighttpd-1.4.13.tar.gzはダウンロード済みの前提)

$ cd ~/install
$ wget http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/~checkout~/SOURCES/lighttpd-mod_extforward-v2.patch?rev=1.2;content-type=text%2Fplain
$ tar zxvf lighttpd-1.4.13.tar.gz
$ cd lighttpd-1.4.13/
$ patch -ls -p1 -i ../lighttpd-mod_extforward- v2.patch\?rev\=1.2

// ↓Lighttpd公式サイトのインストール手順と若干違うので注意
$ autoconf

// configure時のオプションは、お好きなように。
$ ./configure --prefix=/mnt/domain0/dev/lighttpd --with-pcre=/mnt/domain0/dev/lighttpd --with-openssl 
$ make
$ sudo make install


結局は、パッチが公開されているので、パッチを当ててconfigを作り直して、makeしてインストールなのですが、これをやっても、結局「mod_extforward」がインストールできなかった。。。

configureを終了したときに、「mod_extforward」は確かに"enable"として表示されていたのに・・・。


ならば、とMakefileを書き換える・・・のではなく、面倒くさくなったので手動でぶちこみました(笑)
# 良い子の皆さんはできるだけ真似しないように!

$ ll ~/install/lighttpd-1.4.13/src

$ if /bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -DLIBRARY_DIR="\"/mnt/domain0/dev/lighttpd/lib\"" -I. -I. -I..   -D_REENTRANT -D__EXTENSIONS__ -DOPENSSL_NO_KRB5 -I/mnt/domain0/dev/lighttpd/include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES  -g -O2 -Wall -W -Wshadow -pedantic -std=gnu99 -MT mod_extforward.lo -MD -MP -MF ".deps/mod_extforward.Tpo" -c -o mod_extforward.lo mod_extforward.c; \ 
        then mv -f ".deps/mod_extforward.Tpo" ".deps/mod_extforward.Plo"; else rm -f ".deps/mod_extforward.Tpo"; exit 1; fi

$ gcc -DHAVE_CONFIG_H -DLIBRARY_DIR=\"/mnt/domain0/dev/lighttpd/lib\" -I. -I. -I.. -D_REENTRANT -D__EXTENSIONS__ -DOPENSSL_NO_KRB5 -I/mnt/domain0/dev/lighttpd/include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES -g -O2 -Wall -W -Wshadow -pedantic -std=gnu99 -MT mod_extforward.lo -MD -MP -MF .deps/mod_extforward.Tpo -c mod_extforward.c  -fPIC -DPIC -o .libs/mod_extforward.o
 
$ /bin/sh ../libtool --tag=CC --mode=link gcc  -g -O2 -Wall -W -Wshadow -pedantic -std=gnu99   -o mod_extforward.la -rpath /mnt/domain0/dev/lighttpd/lib -module -export-dynamic -avoid-version -no-undefined mod_extforward.lo 

$ gcc -shared  .libs/mod_extforward.o   -Wl,-soname -Wl,mod_extforward.so -o .libs/mod_extforward.so
$ creating mod_extforward.la
$ (cd .libs && rm -f mod_extforward.la && ln -s ../mod_extforward.la mod_extforward.la) 


$ /bin/sh ../libtool --mode=install /usr/bin/install -c  'mod_extforward.la' '/mnt/domain0/dev/lighttpd/lib/mod_extforward.la'
$ /usr/bin/install -c .libs/mod_extforward.so /mnt/domain0/dev/lighttpd/lib/mod_extforward.so 
$ /usr/bin/install -c .libs/mod_extforward.lai /mnt/domain0/dev/lighttpd/lib/mod_extforward.la
$ PATH="$PATH:/sbin" ldconfig -n /mnt/domain0/dev/lighttpd/lib

注:上記の"/mnt/domain0/dev/lighttpd"は、一例であり、この部分には、configure時にprefixで指定したものをあてはめてください。


これで無事インストールできました。lighttpdインストール場所のlibにちゃんと「mod_extforward.so」があったので。
あとは、lighttpdの設定ファイルに以下を追記。

  • server.modules に "mod_extforward" を追加
  • extforward.forwarder にリバースプロキシのIPを書く

例)

server.modules       = ("mod_rewrite", "mod_accesslog", "mod_extforward", "mod_fastcgi", "mod_compress", "mod_expire")
extforward.forwarder = ("127.0.0.1" => "trust")


これで、リバースプロキシ経由でバックエンドのWebサーバ(lighttpd)にアクセスしても、Webサーバのログにはきちんとアクセス元のクライアントIPアドレスが残るようになります。