share facebook facebook twitter menu hatena pocket slack

2012.11.29 THU

ロードバランサー(ELB)経由でなくてもX-Forwarded-Forをつける

鈴木 宏康

WRITTEN BY 鈴木 宏康

Webサーバをロードバランサー(ELB)経由にする時に、Webサーバに設定されるリモートアドレスが、
ユーザー(ブラウザ)のものからロードバランサーのものになってしまうことは有名な話だと思います。

その場合、ELBは(その他の多くのロードバランサーも)X-Forwarded-Forヘッダに、ユーザー(ブラウザ)の
IPアドレスが設定されるので、以前紹介したApacheでREMOTE_ADDRをELB経由でも…(CentOS)の記事の
方法等で対応することが可能です。

そして、あまり無いとは思いますがロードバランサー経由のWebサーバをインターネットからの直接アクセスに
戻す場合もあるかと思います。
(このようなケースがあるとすれば、コスト削減や障害対応等の場合かと思います。)

もし、アプリケーション等でX-Forwarded-Forヘッダを参照している場合、インターネットからの直接アクセスでは
X-Forwarded-Forヘッダは付与されていないので、アプリケーション側で問題が発生してしまうかと思います。

また、アプリケーションを修正するのは、現実的では無い場合が多いのでWebサーバ(Apache)側で
対応したいところです。

このような場合、単にリモートアドレスと同じIPアドレスが設定された、X-Forwarded-Forヘッダが設定されていれば
アプリケーション的にも問題がなくなるはずです。

尚、Apacheの場合は下記のように設定(httpd.conf)を行う事で、上記を実現することが可能です。

 SetEnvIf X-Forwarded-For ".+" forwarded
RewriteEngine On
RewriteRule ^(.*) - [E=CLIENT_ADDR:%{REMOTE_ADDR},L]
RequestHeader set X-Forwarded-For "%{CLIENT_ADDR}e" env=!forwarded

※ロードバランサー(ELB)経由の場合は、そのままのX-Forwarded-Forを利用します。

実際に下記のPHPスクリプトで、ロードバランサー(ELB)経由とインターネットからの直接アクセスでの該当変数を
確認してみました。

 print("REMOTE_ADDR="          . $_SERVER["REMOTE_ADDR"]);
print("forwarded="            . $_SERVER["forwarded"]);
print("CLIENT_ADDR="          . $_SERVER["CLIENT_ADDR"]);
print("HTTP_X_FORWARDED_FOR=" . $_SERVER["HTTP_X_FORWARDED_FOR"]);
?>

ロードバランサー(ELB)経由の場合は、X-Forwarded-Forが下記のようにロードバランサーが
設定したもののままとなります。

インターネットからの直接アクセスの場合は、X-Forwarded-Forに下記のようなリモートアドレスの値が
設定されていました。

当初は、SetEnvIfのみで対応できると思っていました。

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら

鈴木 宏康

鈴木 宏康

愛知県生まれ。東京工業大学大学院修士課程修了。在学時より、ベンチャー企業でインターネットに関する業務に携わり、現在はクラウド(主にAmazon Web Services)上での開発・運用を軸とした事業の、業務の中心として活躍。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。