Squidで多段プロキシ設定 X-Forwarded-For編
今日もSquidです。環境はCentOS7、Squid3.5.2です。
今回はX-Forwarder-For(XFF)を使用します。構成は2台のSquidで多段プロキシとし、1段目のプロキシサーバでXFFヘッダを挿入して2段目プロキシサーバに転送します。
前回の記事を見て頂くと分かるのですが、2段目プロキシサーバのアクセスログでは送信元IPアドレスが全て1段目のプロキシサーバになるため、そのログがどのクライアントのものなのかを追跡することが難しくなります。
XFFヘッダには元々のクライアントIPアドレスが挿入されるため、このHTTPヘッダの値を出力することで2段目プロキシサーバのアクセスログからクライアントとの対応付が可能になります。
必要な設定は非常にシンプルです。1段目のプロキシサーバに以下の設定をします。
forward_for on
これでXFFヘッダが挿入されます。続いて2段目プロキシサーバでアクセスログを見ます。しかし、初期設定ではXFFの値をログに書き出さないため、ログフォーマットの設定を変更します。ログフォーマットのどこかに%{X-Forwarded-For}>hを入れます。こうしてからアクセスログを覗いてみましょう。
はてなブログにアクセスしたところ、以下のログが出力されました。
1533216554.761 86 192.168.0.159 TCP_MISS/200 898 GET http://blog.hatena.ne.jp/api/init? - HIER_DIRECT/13.115.18.61 application/json 02/Aug/2018:22:29:14 +0900 192.168.0.9
赤字部分のIPアドレスが挿入されたXFFの値です。
XFFを消す
以下の画像は2段目プロキシサーバでtcpdumpしたHTTPパケットの一部です。通信内容は2段目プロキシサーバから宛先URLに対する通信です。Squidの初期設定ではViaに値が書き込まれるようなので、経由したプロキシがViaヘッダに書かれています。
そして1段目プロキシサーバでXFFを挿入しているので、当然ながらXFFが差し込まれています。
今回の趣旨は2段目プロキシサーバでクライアントのIPアドレスを表示させることであり、宛先WebサーバにわざわざIPアドレスを知らせる必要はありません。ちなみにですが、プライベートIPアドレスなのでセキュリティ的なリスクは小さいと思います。
そんなわけで、2段目プロキシサーバでXFFを消す設定をしてみます。以下の設定を行います。
forward_for delete
これでXFFヘッダがまるごと削除されます。この状態でtcpdumpしたものが以下の画像です。
XFFがなくなっています。
XFFを話題にした巷のブログ記事と次の記事に向けて
ここからは雑記みたいなものです。
私もHTTPについて熟知しているわけではないので色々と調べながら記事を書いています。色々なブログ記事を見ていると、圧倒的にプログラマ寄りの方の記事が多いですね。AWS等の環境で何らかの理由のためにリバースプロキシをWebサーバの手前に置いている構成がよく見られました。逆にリバースプロキシでない普通のプロキシの記事でXFFに触れている記事は圧倒的に少なかったです。
非暗号化httpであればリバースプロキシで素直にXFFを差し込めばWebサーバ側でクライアントのIPアドレスを取得できます。ところが暗号化http(HTTPS)の場合は若干事情が異なります。暗号化されているため通常はHTTPリクエストやHTTPレスポンスの中身の実際の値を参照や書き換えはできません。これらの操作を行うのであればリバースプロキシで暗号化をほどく必要があります。そのためにはリバースプロキシにWebブラウザが信頼している認証局から発行されたサーバ証明書が必要です(信頼されていなくてもほどけますがWebブラウザがTLSエラーを吐きます)。余談ですが、こうした手法はセキュリティ的な攻撃者も使用するので、攻撃者のサイトに接続しに行ってしまうと暗号化通信の内容を読み取られる可能性があります。
何となく以下の内容を書いたブログが多く、もやっとなったので今後記事のテーマにしていこうと思います。
間違っているわけではないのですが、多分書き方が良くない。