NHN Cloud Meetup 編集部
Proxyモードロードバランサ利用時のクライアントIPロギング(TOASTサービスをのぞいてみる)
2018.08.31
3,879
ロードバランサとは?
基本的にLBは外部から入ってきた要求に対し、内部にあるサーバーで負荷を分散する目的で使用されています。自主的に内部サーバーの状態をチェックして、サービスが不可能なサーバーへにはトラフィックを送信しない、またヘルスチェック機能をサポートするため、負荷分散だけでなく、HAの用途にも多く利用されるインフラストラクチャソリューションです。
要求フロー
外部から入ってきた要求は大きくDSR(Direct Server Return)とProxyの二つのモードのトラフィックフローを持つことができます。DSRの場合、下図のように、ユーザーからのリクエストに対して、サーバーが直接回答します。Proxyモードの場合、LBを介して回答を与えます。DSRモードでは、ロードバランサを介して回答する形がないので、ロードバランサの負荷を少なくし、応答がサーバーから直接発信する特性からProxy方式に比べて高速な応答レイテンシーを持つことができるという利点があります。しかし、DSRを利用するには、すべてのサーバーにloopback形態の設定を追加する不便さがあります。
TOASTを含むほとんどのCloudメーカーから提供されるロードバランサは、Proxyモードの要求フローを提供しています。
X-Forwarded-For
Proxyモードでロードバランサが動作するために、クライアントはロードバランサと連結し、ロードバランサはサーバーへの接続を結ぶ形になります。この時、Source IPをロードバランサのIPに変更してサーバーに要求します。この場合、サーバーでは実際のクライアントのIPアドレスが分からないので、要求者の実際のIPアドレスをログに残すことができなくなります。このような理由から、HTTP / HTTPSでは、X-Forwarded-Forヘッダを利用して、クライアントのIPアドレスを調べることができる方法を提供します。TOASTロードバランサは、Proxyモードの要求フローを提供し、モードのHTTP要求に対して、X-Forwarded-Forヘッダを追加してサーバーに渡します。
X-Forwarded-Forヘッダはclient、proxy ipが順番に記録されます。
X-Forwarded-For: client ip, proxy ip
WebサーバーのlogにクライアントIPを残す
X-Forwarded-Forヘッダを利用してApache、nginxのログにクライアントのIPアドレスを記録する方法を説明します。
Apache
Apache Webサーバーの場合、デフォルトのログ設定は以下の通りです。
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined CustomLog logs/access_log combined
この場合、クライアントのIPアドレスが正常にログに記録されないので、以下のような形に変更する必要があります。
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy CustomLog logs/access_log proxy
設定変更後、Apache Webサーバーを再起動すると、適用されたログを確認できます。
nginx
nginxでX-Forwarded-Forヘッダを利用するには、\, –with-http_realip_moduleが一緒にコンパイルされたバイナリが必要です。
基本的に–with-http_realip_moduleモジュールは一緒に使用できるようにインストールされます。
モジュールがインストールされているかどうかは、nginx -Vから確認できます。
[root@host-192-168-0-88 ~]# nginx -V nginx version: nginx/1.10.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E'
インストールされている場合は、/etc/nginx/nginx.confを開き、httpセクションに$http_x_forwarded_forが含まれていることを確認してください。ない場合は追加すればOKです。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main;