「あれ、IPアドレスが全部同じ?」プロキシ越しの通信で“本当の送信者”を見抜く魔法のヘッダー
Webエンジニアとして働き始めると、一度はぶつかる壁があります。それは、「アクセスログを見ても、IPアドレスがロードバランサー(プロキシ)のものばかりで、実際のユーザーのIPがわからない!」という問題です。
今日は、インターネットという広大な世界で、郵便物をリレーしながら届ける仕組みと、その中でどうやって「本当の差出人」を特定するのか、その秘密兵器である「X-Forwarded-For」についてお話ししましょう。
—
1. なぜ「本当のIP」が見えなくなるの?
まず、身近な例で考えてみましょう。
あなたが海外の友人に手紙を送るとします。直接送るのではなく、「国際配送センター」を経由して送ることにしました。届いた手紙の封筒に書かれている差出人住所は、あなたの住所ではなく「国際配送センター」の住所になってしまいますよね。
Webの世界もこれと同じです。
ユーザーがWebサイトにアクセスするとき、間に「プロキシ(中継サーバー)」や「ロードバランサー」が入ると、Webサーバー(オリジンサーバー)から見た通信の相手は、ユーザー本人ではなく「中継サーバー」になってしまうのです。
これでは、アクセス制限をかけたり、地域ごとの解析をしたりするときに困ってしまいますよね。そこで登場するのが、X-Forwarded-For (XFF) です。
2. X-Forwarded-Forは「追記される付箋」
X-Forwarded-Forは、プロキシサーバーが「元の送信者のIPアドレス」を記録しておくための、いわば「封筒の端っこに貼られた追記用の付箋」のようなものです。
通信の流れはこうなります。
1. ユーザー(IP: 1.1.1.1)がアクセスする。
2. プロキシサーバー(IP: 2.2.2.2)がそれを受け取る。
3. プロキシサーバーが、HTTPヘッダーに `X-Forwarded-For: 1.1.1.1` という付箋を貼って、Webサーバーに転送する。
4. Webサーバーは、その付箋を見て「ああ、本当の送信者は1.1.1.1さんなんだな」と理解する。
もし複数のプロキシを通過した場合は、付箋がどんどん増えていきます。
`X-Forwarded-For: 1.1.1.1, 192.168.0.10, 10.0.0.5`
(左端が一番最初のクライアント、右に行くほど直前に通過したサーバー)
3. 実践!Webサーバーで確認してみよう
実際にWebサーバーでこのヘッダーを受け取る際、どのように見えるのか確認してみましょう。Nginxを例に設定を見てみます。
Nginxの設定例
location / {
# プロキシから渡されたヘッダーを、ログの変数にセットするイメージです
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ここに実際のクライアントIPを記録します
# $remote_addr だとプロキシのIPしか取れないので注意!
}
アプリケーション側(PHPなど)で取得する場合はこんな感じです。
4. 知っておくべき「セキュリティの罠」
ここで一つ、非常に重要な注意点があります。
「X-Forwarded-Forは、誰でも自由に書き込めるヘッダーである」ということです。
もし悪意のあるユーザーが、自分のパソコンからわざと「偽のX-Forwarded-Forヘッダー」を付けてWebサーバーに送ったらどうなるでしょうか?サーバーがその情報を無条件に信じてしまうと、本来アクセス禁止にすべきユーザーを許可してしまったり、ログが改ざんされたりするリスクがあります。
インフラ担当者の鉄則
- 信頼できるプロキシからの値だけを信じる:
Webサーバーの前段に置いたロードバランサーやプロキシサーバーの設定でのみ、このヘッダーを付与(または書き換え)するように厳密に管理しましょう。
- クライアントからの直接入力は信頼しない:
インターネット越しに直接届いたパケットのXFFヘッダーを、そのまま鵜呑みにするのはNGです。
まとめ:一歩ずつ進んでいきましょう
プロキシ越しの通信は、最初は少し複雑に感じるかもしれません。でも、「郵便のリレー」と「付箋の追記」という仕組みさえイメージできれば、もう怖くありません。
1. プロキシを通るとIPが書き換わる
2. XFFヘッダーで元のIPをバケツリレーする
3. ただし、ヘッダーは偽造可能なので「信頼できる相手」のものだけを採用する
この3つのポイントを押さえるだけで、あなたのネットワークトラブルシューティング能力は確実に一段上がります。ぜひ、現場のログや設定ファイルを見るときに、「このパケットは今どこで付箋を貼られたのかな?」と想像してみてくださいね。
それでは、また次の技術解説でお会いしましょう!
コメント