nginx real_ip_headerとX-Forwarded-Forが間違っているようです


59

HTTPヘッダーのウィキペディアの説明X-Forwarded-Forは次のとおりです。

X-Forwarded-For:client1、proxy1、proxy2、...

ディレクティブのnginxドキュメントにはreal_ip_header、次の部分があります。

このディレクティブは、置換IPアドレスの転送に使用されるヘッダーの名前を設定します。
X-Forwarded-Forの場合、このモジュールはX-Forwarded-Forヘッダーの最後の IPを置換に使用します。[エンファシス鉱山]

これらの2つの説明は、相反するように見えます。このシナリオでは、X-Forwarded-Forヘッダーは説明したとおりです。クライアントの「実際の」IPアドレスは左端のエントリです。同様に、nginxの動作は、右端の値を使用することです。これは、明らかにプロキシサーバーの1つにすぎません。

私の理解でX-Real-IPは、プロキシではなく実際のクライアントIPアドレスを決定するために使用されることになっています。私は何かを見逃していますか、これはnginxのバグですか?

そして、それを超えて、誰でも作る方法について何か提案していないX-Real-IPヘッダが表示され、左の定義によって示されるように、 -ほとんどの値はX-Forwarded-For

回答:


97

複数のIPがチェーンされているときにX-Forwarded-Forの問題を解決する鍵は、最近導入された構成オプションreal_ip_recursive(nginx 1.2.1および1.3.0で追加)であると思います。nginxのrealipドキュメント

再帰検索が有効になっている場合、信頼できるアドレスの1つと一致する元のクライアントアドレスは、要求ヘッダーフィールドで送信された最後の信頼できないアドレスに置き換えられます。

デフォルトでは、nginxはチェーン内の最後のIPアドレスを取得していました。これは信頼できると想定された唯一のIPアドレスだったからです。ただし、新しいオプションをreal_ip_recursive有効にして複数のset_real_ip_fromオプションを使用すると、複数の信頼されたプロキシを定義でき、最後の信頼されていないIPを取得します。

たとえば、この設定では:

set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

X-Forwarded-Forヘッダーにより、次の結果が得られます。

X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1

nginxは、クライアントのIPアドレスとして123.123.123.123を選択します。

nginxが左端のIPアドレスを選択するだけでなく、信頼できるプロキシを明示的に定義する必要があるのは、簡単なIPスプーフィングを防ぐためです。

クライアントの実際のIPアドレスがであるとしましょう123.123.123.123。また、クライアントは役に立たず、IPアドレスを偽装しようとしているとします11.11.11.11。彼らは、このヘッダーを既に配置した状態でサーバーにリクエストを送信します。

X-Forwarded-For: 11.11.11.11

リバースプロキシはこのX-Forwarded-Forチェーンに単にIPを追加するだけなので、nginxが到達すると、次のようになります。

X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1

一番左のアドレスを取得するだけで、クライアントはIPアドレスを簡単にスプーフィングできます。しかし、上記の例のnginx configでは、nginxは最後の2つのアドレスのみをプロキシとして信頼します。これは123.123.123.123、その偽装されたIPが実際に一番左にあるにもかかわらず、nginxがIPアドレスとして正しく選択することを意味します。


2
これをどうもありがとう、本当に助けてくれました。これは受け入れられた答えであるはずです。
ホセF.ロマニエッロ

1
デフォルトではX-のReal-IPは、に応じてあるように見えるreal_ip_header nginx.org/en/docs/http/ngx_http_realip_module.htmlだけランダムX-のReal-IPでリクエストを送信することができ、それは、悪意のあるユーザーを意味していて、そのはREMOTE_ADDR $として使用されますnginxで(そしておそらくアプリケーションに渡されます)?
ガンスブレスト14

@gansbrestいいえ。set_real_ip_fromは信頼できるホストを制限するためです。
エルヨボ

9

X-Forwarded-Forヘッダーの解析は、実際にはnginx real_ipモジュールに欠陥があります。

len = r->headers_in.x_forwarded_for->value.len;
ip = r->headers_in.x_forwarded_for->value.data;

for (p = ip + len - 1; p > ip; p--) {
  if (*p == ' ' || *p == ',') {
    p++;
    len -= p - ip;
    ip = p;
    break;
  }
}

ヘッダー文字列の右端から開始し、スペースまたはコンマが表示されるとすぐに検索を停止し、IP変数のスペースまたはコンマの右側に部品を貼り付けます。そのため、最新のプロキシアドレスを元のクライアントアドレスとして扱っています。

仕様によるとうまく動作していません。これは、RFCで痛々しいほど明白な用語で綴られていない危険です。

脇:それももともとイカで定義されたフォーマット、上の優れた主要なソースを見つけるのは難しいです-彼らを通して掘るドキュメントには、順序を確認します。左端は元のクライアント、右端は最新の追加です。そのウィキペディアのページに[要出典]を追加したいのです。匿名の編集の 1つは、この件に関するインターネットの権限のようです。

可能であれば、中間プロキシにヘッダーの末尾への追加を停止させ、実際のクライアントアドレスのみを残してもらえますか?


返信ありがとう、@ Shane。実際、nginxに到達X-Forwarded-Forすると、すでに存在します。(正しいクライアントIPアドレスです) nginx自体は、ロードバランサー(前のホップ)のIPアドレスをX-Forwarded-Forヘッダーに追加します。(おそらく「リモートアドレス」と見なされるものを追加します)単にそれを行わなかったX-Forwarded-For場合、以前のようにヘッダーを使用することができます。(最近nginxに移行しています)
カークウォル

@Kirkそれでは、nginxがヘッダーを取得するとき、それは単に元のクライアントのアドレスですか?しかし、それを処理しているときに、接続しているプロキシサーバーのヘッダーに追加されますか?それは合計しません-そのヘッダーに触れる必要があるのは、それが別のプロキシにa経由で接続を送信しているときproxy_passだけです-そしてそれでも、適切なproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;場所でのみです。
シェーンマッデン

でも、W3Cは、この間違ったを取得します:彼らのドキュメントには、「プロキシがへの要求のイニシエータのIPアドレスを追加する必要があります述べエンド X-転送さ-のためにHTTPヘッダフィールドにカンマ区切りリストの」、それは必ず明記してください始まります
イアン・ケンプ

3
@IanKemp、いいえ、終わりは正しいです。プロキシのサーバー側にとって、リクエスト(つまりTCPリクエスト)のイニシエーターは前のプロキシ(存在する場合)です。その前のプロキシX-Forwarded-Forは、おそらく左側に元のクライアントアドレスと、それに追加された先行プロキシを含むヘッダーを既に送信している可能性があります。そのため、現在サービスを提供しているプロキシは、そのリストの最後に前のプロキシ(=イニシエータ)を追加し、このように拡張されたX-Forwarded-Forヘッダーを次のアップストリームホップに提供します。確かに、彼らはより明白な言葉遣いを選んだかもしれません。
-blubberdiblub

5

X-Real-IPは、サーバーが通信している実際のクライアント(サーバーの「実際の」クライアント)のIPアドレスであり、プロキシ接続の場合はプロキシサーバーです。X-Real-IPがX-Forwarded-Forヘッダーの最後のIPを含むのはそのためです。


1
わかりましたが、私にとっては、これは決して有用な情報ではありません。クライアントの元のIPアドレスを取得したい-これは非常に重要であり、私が読んだすべての情報によれば、これらのヘッダーの目的です。プロキシサーバーのIPアドレスを知りたいのはなぜですか?
カークウォル

それがあなたにとって役に立たないなら、それはあなたのためではありません。X-Real-IPの使用を強制する人はいません。アプリケーションでユーザーのIPが必要な場合は、アプリケーションにX-Forwarded-Forを解析させます(X-Forwarded-を設定しないプロキシ(インターネットセキュリティアプライアンス/ファイアウォール)があるため、常に信頼できるとは限りません)ために)。nginxのコンテキストでは、X-Forwarded-Forは重要ではありません。なぜなら、nginxのクライアントである最後のエントリ(X-Real-IP)を除き、X-Forwarded-Forはクライアントと通信していないからです。必要ない場合は、設定しない、設定を解除する、または単に無視する:/
user558061

2
いいえ、私は何を意味するか、なぜでしょうX-Real-IP私自身のプロキシサーバーのIPアドレスを返すこれまで便利?
カークウォル

すごい。この正確な情報を探していました。プロキシサーバー上のncatサーバーと通信する必要があるため、その場で必要です。
ユガルジンドル12年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.