web-dev-qa-db-ja.com

CloudFront経由でリクエストのクライアントIPを取得するにはどうすればよいですか?

CloudFrontのドキュメントによると( https://docs.aws.Amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html )、クライアントIPはX-Forwarded-Forヘッダーのフロント、ミドル、エンドになることができます。

厳格ですか?では、どうすれば実際のクライアントIPを取得できますか?

5
mayTree

正しいですか?

ではない正確に。

CloudFrontはX-Forwarded-Forの正しいセマンティクスに従います。具体的には、リクエストを処理する各システムは、クライアントのアドレスを右側に追加します。これは、CloudFrontからのリクエストのX-Forwarded-Forの右端のアドレスが、常にCloudFrontに接続したマシンのアドレスであることを意味します。

クライアント(CloudFrontへの接続を確立するマシン)のリクエストにX-Forwarded-Forヘッダーが含まれている場合、そのヘッダーは偽造されているか、クライアントがプロキシサーバーである場合は正当なものである可能性がありますが、それを知っている...どちらの方法でも、これは潜在的に価値があるが、厳密には権限がないものとして扱う必要があります。

右端の値(唯一の値である場合もあります)は、CloudFrontから受け取るリクエストで信頼できる唯一の値です。

一般的に言えば、右から解析すると、上流のクライアントを正しく識別したことがわかっていて信頼できるアドレスはリストから削除できます...しかし、最初の信頼できないアドレスを右から左に見つけたら、それがあなたのアドレスです。探しているのは、そのアドレスの左側には信頼できるものがないためです。

これは、スタック内のコンポーネント(Application Load BalancerやWebサーバーなど)もX-Forwarded-Forを追加している場合、それらのコンポーネントも考慮する必要があることを意味します値の右側に追加し、CloudFrontが提供するものを変更します。

例えば。クライアントが送信:

X-Forwarded-For: a, b, c

CloudFrontがクライアントのIPを追加しますd

X-Forwarded-For: a, b, c, d

ALBはCloudFrontからリクエストを受信するため、CloudFront出力アドレスeを追加します。

X-Forwarded-For: a, b, c, d, e

次に、Webサーバーがバランサーの内部アドレスfを追加します。

X-Forwarded-For: a, b, c, d, e, f

バランサーサブネットのCIDR範囲内であれば、fを信頼して削除できます。

CloudFront アドレス範囲 にある限り、eを信頼して削除できます。

これにより、クライアントアドレスとしてwith dが残ります。

この例では、abcの値はalmostに価値がありません。最初の(右から)信頼されていないアドレスの左側にあるため、その信頼性を信頼できません...後で、法医学的に役立つ場合がありますが、それらに基づいてリアルタイムの決定を行うことはできません。

これがX-Forwarded-Foralwaysの仕組みです。理解不足のため、多くの開発者はナイーブな仮定をしているようです。重要なものに使用する前に、必ず理解してください。


Lambda @ Edge トリガーでは、CloudFrontはevent.Records[0].cf.request.clientIpでクライアントIPアドレスを提供します。これは常に単一のアドレスであり、リクエストがCloudFrontをオリジンに向けたままにするため、X-Forwarded-Forの右端の値と同じです(前述のように、右側に値が追加される場合があります)。

11