如何通过 CloudFront 获取请求的客户端 IP? [英] How to get client IP of requests via CloudFront?

查看:32
本文介绍了如何通过 CloudFront 获取请求的客户端 IP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 CloudFront 的文档(https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html),客户端 IP 可以是 X-Forwarded-For 标头的前、中、尾.

是否正确?那么如何获取真实的客户端IP呢?

解决方案

对吗?

不完全是.

CloudFront 遵循 X-Forwarded-For 的正确语义.具体来说,每个处理请求的系统都会将其客户端地址附加到右侧.这意味着来自 CloudFront 的请求中 X-Forwarded-For 中最右边的地址始终是连接到 CloudFront 的机器的地址.

如果客户端(与 CloudFront 建立连接的机器)在其请求中包含 X-Forwarded-For 标头,则该标头可能是伪造的,如果客户端是代理服务器,但您很少知道...

最右边的值(也可能是唯一的值)是您从 CloudFront 收到的请求中唯一可以信任的值.

一般来说,从右边解析,任何你知道的并且信任已经正确识别其上游客户端的地址都可以从列表中删除......但是一旦你遇到第一个不受信任的地址,从右到左,那就是您正在寻找的那个地址,因为该地址左侧的任何内容都不可信.

这意味着如果您的堆栈中的组件——例如应用程序负载均衡器或您的 Web 服务器也添加了 X-Forwarded-For,那么您将需要考虑这些组件also 添加到值的右侧,修改 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

然后你的网络服务器添加平衡器的内部地址f:

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

您可以信任和删除 f,只要它在您的平衡器子网的 CIDR 范围内即可.

您可以信任和删除 e,只要它在 CloudFront 地址范围.

这样您就可以将d 作为客户端地址.

abc 几乎 毫无价值,在这个例子中,因为你可以不要相信它们的真实性,因为它们位于第一个(从右侧起)不受信任地址的左侧……偶尔,它们可能在以后在取证方面很有用,但您无法根据它们做出任何实时决策.

这就是 X-Forwarded-For 总是 的工作方式.由于缺乏理解,许多开发人员似乎做出了幼稚的假设.在将它用于任何重要的事情之前,请确保您理解它.

<小时>

Lambda@Edge 触发器中,CloudFront 在 event.Records[0].cf.request.clientIp 中为您提供客户端 IP 地址.这始终只是一个地址,并且与 X-Forwarded-For 最右边的值相同,因为请求将 CloudFront 发送到您的源(如上所述,它可能会在右侧).

According to the doc of CloudFront (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html), client IP can be the front, middle, end of X-Forwarded-For header.

Is it rignt? Then how can I get real client IP?

解决方案

Is it right?

Not exactly.

CloudFront follows correct semantics for X-Forwarded-For. Specifically, each system handling the request appends its client's address to the right. This means the rightmost address in X-Forwarded-For in the request from CloudFront is always the address of the machine that connected to CloudFront.

If the client (the machine establishing the connection to CloudFront) includes an X-Forwarded-For header in its request, that header may be forged, or it may be legitimate if the client is a proxy server, but you rarely have a way of knowing that... so either way, you should treat this as potentially valuable, but strictly non-authoritative.

The rightmost value (which may also be the only value) is the only value you can trust in the request you receive from CloudFront.

Generally speaking, parsing from the right, any address that is known to you and trusted to have correctly identified its upstream client can be removed from the list... but once you encounter the first untrusted address, right to left, that's the one you're looking for, since nothing to the left of that address can be trusted.

This means that if components in your stack -- such as Application Load Balancer or your web server are also adding X-Forwarded-For, then you will need to account for what those components also add onto the right side of the value, modifying what CloudFront has supplied.

For example. Client sends:

X-Forwarded-For: a, b, c

CloudFront adds the client's IP d:

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

ALB receives the request from CloudFront, so it adds the CloudFront egress address e:

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

Then your web server adds the internal address of the balancer f:

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

You can trust and remove f as long as it is with the CIDR range of your balancer subnets.

You can trust and remove e as long as it is in the CloudFront address ranges.

That leaves you withd as the client address.

The values a and b and c are almost worthless, in this example, because you can't trust their authenticity since they are to the left of the first (from the right) untrusted address... occasionally, they may be forensically useful, later, but you can't make any real-time decisions based on them.

This is how X-Forwarded-For always works. Many developers seem to make naïve assumptions due to lack of understanding. Be certain you understand it before you use it for anything important.


In Lambda@Edge triggers, CloudFront gives you the client IP address in event.Records[0].cf.request.clientIp. This is always just a single address, and is the same as the rightmost value of X-Forwarded-For as the request leaves CloudFront headed to your origin (which may, as noted above, add additional values onto the right side).

这篇关于如何通过 CloudFront 获取请求的客户端 IP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆