X-Forwarded-For
X-Forwarded-For とは、HTTPヘッダフィールドの1つです。HTTPプロキシサーバやロードバランサを経由して、Webサーバに接続するクライアントの送信元IPアドレスを伝搬するために用いられます。
読み方
- X-Forwarded-For
- えっくす ふぉわーでぃっど ふぉー
目次
概要
WebサーバにウェブブラウザなどのHTTPクライアントがアクセスするときに、ドキュメントを提供するサーバに直接接続されるとは限りません。キャッシュなどを目的に、プロキシが利用するケースが考えられます。
client -> origin_server client -> proxy1 -> origin_server client -> proxy1 -> proxy2 -> origin_server
Slowlorisの対策として、Apache HTTP Serverの前にnginxなどをプロキシとして置くような手法もあります。
HTTPのアクセスをプロキシするときに、Webサーバは接続元を知ることができるでしょうか?ソケットレベルで考えれば、ソケットレベルで直接接続されているクライアントを知ることができますが、その接続元がHTTPリクエストを作成した起源となっているクライアントかどうかは、わかりません。
X-Forwarded-Forは、リクエストを送信してきたクライアントをHTTPのリクエストチェインに通知するために使用されます。 HTTPのリクエストチェインというのは、HTTPリクエストが後続のWebサーバにパスしていくことです。
client -> proxy1 -> proxy2 -> origin_server
X-Forwarded-Forのフォーマット
X-Forwarded-Forのフォーマットは、以下のとおりです。IPアドレスをカンマ区切りで表現します。
X-Forwarded-For: client1, proxy1, proxy2
例えば、以下のプロキシを1つ通過する場合、
client -> proxy1 -> origin_server
origin_serverは、以下のフィールドを持つHTTPリクエストヘッダを受信します。
X-Forwarded-For: client1
使い方
もし、X-Forwarded-Forでアドレスが渡ってきているとすれば、以下のコードでクライアントのIPアドレスを取得できます。
PHPでX-Forwarded-Forを取得する方法
もし、X-Forwarded-Forでアドレスが渡ってきているとすれば、$_SERVER変数に設定されています。
<?php $clientip = $_SERVER['HTTP_X_FORWARDED_FOR']; ?>
apache_request_headers()でも取得できます。
<?php var_dump ( apache_request_headers()['X-Forwarded-For']); ?>
X-Forwarded-Forの信頼性
X-Forwarded-Forは、自由に設定できるため、信頼性があるものではありません。 自分の管理下にあるシステムで設定されたX-Forwarded-Forのフィールドに関しては、信頼しても構いませんが、自分の管理下にはない、インターネットからやってきたリクエストにのってきたX-Forwarded-Forフィールドは、信頼性はありません。そのため、あくまでも参考程度に使用するべきです。
ロギング
ログを保存する場合には、Webサーバの接続元とX-Forwarded-Forフィールドの両方を記録するべきです。
Apacheの設定
X-Forwarded-Forをログに落とす場合には、以下のような設定が必要です。
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b"
関連項目
- Apache mod_remoteip
- X-Forwarded-For
- Via
- HTTP Cookie
- Set-Cookie
ツイート