ネットワークエンジニアのITブログ

長らくネットワークで生活してきましたが、ここ数年クラウドとサーバー系に触れる機会が増えて、日々成長しています。最近のお気に入りはNSXALBとGoogle Cloud。

NSXALBのX-Forwarded-Forを調べてみた

NSXALBによるHTTP/HTTPSアクセスした際の負荷分散は、基本的にSNATをしてサーバに転送するため、サーバのアクセスログを確認すると、送信元のIPアドレスはSEになっています。
アクセス元の情報が知りたい場合は、HTTP HeaderにX-Forwarded-For(XFF)の情報を付与する必要があります。
NSXALBのXFFヘッダー処理は、3種類の設定があるのでそれぞれ動作について見ていきます。

構成

ベースのネットワーク構成はこちらになります。

接続テストは、直接クライアントからNSXALBに接続すると、XFFの設定差異がわからないので、クライアントからプロキシサーバを経由してNSXALBに接続し、負荷分散する構成とします。
一応、プロキシサーバありと、なしの接続を設定毎に実施します。

Application Profileの作成

XFFの設定は、Application Profileで行います。
デフォルトでSystem-HTTP が用意されていますが、ラボ環境では、新規に作成してみます。
[Templates]-[Profiles]-[Application]から「CREATE」を選択します。

パターン1:受信したXFF HeaderをNSXALBで作成したXFFで置き換える

以下の情報を入力します。
Name:System-HTTP_XFF
Type:HTTP
X-Forwarded-For:有効
XFF Alternate Name:X-Forwarded-For
XFF Header Handling:Replace all incoming X-Forward-For headers with the Avi created header(すべての受信 X-Forward-For ヘッダーを Avi で作成されたヘッダーに置き換えます)★パターン1



パターン2:受信したXFF HeaderにNSXALBのXFFで追記する

以下の情報を入力します。
Name:System-HTTP_XFF
Type:HTTP
X-Forwarded-For:有効
XFF Alternate Name:X-Forwarded-For
XFF Header Handling:All incoming X-Forwarded-For headers will be appended to the Avi created header(すべての受信 X-Forwarded-For ヘッダーは、Avi が作成したヘッダーに追加されます)★パターン2

パターン3:受信したXFF HeaderにNSXALBで作成したXFF Headerを新たに追加する

以下の情報を入力します。
Name:System-HTTP_XFF
Type:HTTP
X-Forwarded-For:有効
XFF Alternate Name:X-Forwarded-For
XFF Header Handling:Simply add a new X-Forwarded-For header(新しい X-Forwarded-For ヘッダーを追加するだけです)★パターン3

Virtual ServiceとApplication Profileの紐付け

Virtual Serviceの作成手順は割愛しますが、Application Profileで作成した「System-HTTP_XFF」を選択します。


動作確認

それぞれのパターンで、クライアントからプロキシ経由あり、なしでNSXALBのVIPに接続した際に、NSXALBとWebサーバ間のパケットをキャプチャしました。

パターン1:受信したXFF HeaderをNSXALBで作成したXFFで置き換える

この設定は、受信したパケットにXFF Headerがあったとしても、NSXALBで作成したXFFに置き換えるため、元々あったHeaderは削除されます。

プロキシサーバを経由せずにアクセスした場合は、クライアントIPの192.168.100.17がXFFにセットされています。

プロキシサーバを経由した場合は、プロキシサーバーでクライアントIPの192.168.100.17がXFFにセットされますが、NSXALBでプロキシサーバの192.168.1.32に置き換えられているため、クライアントIPの情報はありません。

パターン2:受信したXFF HeaderにNSXALBのXFFで追記する

この設定は、受信したパケットにXFF Headerがある場合、NSXALBで作成したXFFに元の情報を追記します。受信したパケットにXFFがない場合は、自身が作成したXFFを付与します。

プロキシサーバを経由せずにアクセスした場合は、クライアントIPの192.168.100.17がXFFにセットされています。

プロキシサーバを経由した場合は、元々プロキシサーバーでセットしていたクライアントIPの192.168.100.17情報の後ろに、NSXALBで作成したXFFにプロキシサーバの192.168.1.32をセットします。

パターン3:受信したXFF HeaderにNSXALBで作成したXFF Headerを新たに追加する

この設定は、受信したパケットにXFF Headerがある場合、NSXALBで作成したXFFに元の情報を追記します。受信したパケットにXFFがない場合は、自身が作成したXFFを付与します。

プロキシサーバを経由せずにアクセスした場合は、クライアントIPの192.168.100.17がXFFにセットされています。

プロキシサーバを経由した場合は、プロキシサーバで作成したXFF Header(クライアントIPの192.168.100.17)を残したまま、新たにNSXALBで作成したXFF Headerにプロキシサーバの192.168.1.32をセットして、Header情報そのものを追加します。

結果

パターン毎の結果は以下の通りです。
NSXALBのデフォルト動作は、パターン1のNSXALBが作成したXFFのみが追加される形のなります。
パターン2,3の違いは、XFF Header1つの中に複数の送信元情報をセットする(パターン2)か、元々のXFF Headerは変更せずに、新たにXFF Headerを追加する(パターン3)かになります。
また、送信元の情報が表示される順序がパターン2,3では逆になります。

パターン XFF Header処理 補足
1.Replace all incoming X-Forward-For headers with the Avi created header 受信したXFF HeaderをNSXALBで作成したXFFで置き換える 元々のXFFは削除される
2.All incoming X-Forwarded-For headers will be appended to the Avi created header 受信したXFF HeaderにNSXALBのXFFで追記する 元々のXFFを自身のXFF Header内に追加する
3.Simply add a new X-Forwarded-For header 受信したXFF HeaderにNSXALBで作成したXFF Headerを新たに追加する 元々のXFF Headerの後に自身のXFF Headerを追加する

NSXALBに到達する前に、どのような形でXFFが設置されているかによりますが、不特定多数に公開している場合などは、色々なパターンが考えられるのと、あえて、プロキシサーバを経由しているということを知られたくない場合は、自身の情報のみセットすることも考えられます。
この辺は、アプリケーションで送信元情報をどのように利用しているか確認してどのようにサーバへ渡してあげるかを決定するのが良いのかなと思います。