web-dev-qa-db-ja.com

HaproxyがX-Forwarded-Forヘッダーを適切に渡さない

Haproxy-> nginx-> fastcgiを介してリクエストを受信するバックエンドWebサーバーがあります。 Webアプリは、X-Forwarded-Forヘッダーで複数のIPが通過し、コンマでチェーンされていることを確認していました(左側のほとんどの元のIP)。

最近のある時点で(気付いたばかりなので、原因がわからない)、何かが変更されました。現在、ヘッダーでWebアプリケーションに渡されるIPは1つだけです。

同じ動作でhaproxy1.4.21と1.4.22(最近のアップグレード)を試してみました。 Haproxyにはforwardforヘッダーセットがあります:

option forwardfor

Nginx fastcgi_params configは、アプリに渡されるこのヘッダーを定義します。

fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;

ここで何がうまくいかないのか、誰かアイデアがありますか?

EDIT: $ http_x_forwarded_for変数をnginxログに記録し始めたところ、nginxは単一のIPしか表示していませんが、haproxy IPが常に追加されているので、そうではないはずです。そこにありますよね?したがって、問題は、入ってくる変数のnginx処理にあるか、haproxyがそれを適切に構築していないことにある必要があります。掘り続けます...

EDIT#2: HAProxyでリクエストとレスポンスのヘッダーロギングを有効にしましたが、X-Forwarded-Forに何も吐き出されていません。これは非常に奇妙に思えます。

10月10日10:49:01newark-lb1 haproxy [19989]:66.87.95.74:47497 [10/Oct/2012:10:49:01.467] http service/newark2 0/0/0/16/40 301 574 --- ---- 4/4/3/0/0 0/0 {} {} "GET/2zi HTTP/1.1" O

フロントエンドでこれに設定したオプションは次のとおりです。

mode http
option httplog
capture request header X-Forwarded-For len 25
capture response header X-Forwarded-For len 25
option httpclose
option forwardfor

EDIT#3: haproxyがヘッダーを変更し、1つのヘッダーをバックエンドに渡しているようです。これは私たちの制作サービスにかなりの影響を与えるので、誰かがアイデアを持っているならそれは大いにありがたいです。私は困惑しています... :(

3
JesseP

コメントの最後の質問に答えるために、XFFには複数のIPアドレスがあるのが普通です。このヘッダーは値のリストであり、プロキシはクライアントのアドレスをそこに追加することがよくあります。ロングチェーンの全員がそこに値を追加するため、サーバーはそれらを逆の順序で使用する必要があります。たとえば、最後の値はサーバーの前にあるhaproxyインスタンスによって追加された値になり、前の値はhaproxyなどの前にリバースキャッシュによって追加された値になります。

ヘッダーを正しく解析するようにアプリケーションを適合させたくない場合は、独自のXFFヘッダーを追加する前にhaproxyに削除するように依頼することもできます。

reqidel ^X-Forwarded-For:

そうすれば、サーバーは、haproxyのクライアントとなるhaproxyによって追加された値のみを取得します。

2
Willy Tarreau

X-Forwarded-Forヘッダーの使用方法に混乱があると思います。

まず、nginxが1つのIPアドレスを認識するという事実は、haproxyがそれを正しく追加することを意味します。ヘッダーには、haproxyが接続を受信した送信元アドレスのみが含まれているため、nginxログにhaproxyのIPアドレスが表示されないのは通常のことです。

次に、一部の送信プロキシのみがヘッダーを追加するため、受信リクエストでx-forwarded-forが監視されないことも予想されますが、一般に、インターネットにアクセスするときは追加しないことをお勧めします。一部のユーザーがそのようなヘッダーを使用してリクエストを送信すると、haproxyのキャプチャに表示され、nginxはこの値とhaproxyによって追加されたクライアントのIPの両方をログに記録します。

Haproxyのキャプチャとnginxログの両方から判断すると、ヘッダーは受信リクエストに必ず存在すると想定しているようですが、明らかにそうではないため、私が理解していないのはポイント3です。 「X-Forwarded-For:こんにちは、ジェシー、これはウィリーです」というリクエストを送信しました。トラブルシューティングに役立つ場合は、haproxyログとnginxログの両方に表示されます。

可能性があるのは、メインの訪問者の1人がXFFヘッダーを追加した発信プロキシを使用していたため、またはhaproxyの前に別のリバースプロキシ(例:Apache、stunnel)があったために、以前は複数のアドレスが表示されていた可能性があります、...)。

ところで、「optionhttpclose」を「optionhttp-server-close」に置き換える必要があります。これにより、クライアントとのキープアライブが可能になり、待ち時間が長くなるユーザーのページの読み込み時間が短縮されます。

0
Willy Tarreau