首页 > 解决方案 > 如何通过 CloudFront 获取请求的客户端 IP?

问题描述

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

是正的吗?那我怎样才能得到真实的客户端IP呢?

标签: amazon-cloudfront

解决方案


这样对吗?

不完全是。

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

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

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

f只要它在平衡器子网的 CIDR 范围内,您就可以信任并删除它。

e只要它在 CloudFront地址范围内,您就可以信任并删除它。

这使您d成为客户地址。

在此示例中,值 和 几乎毫无价值,a因为您不能相信它们的真实性,因为它们位于第一个(从右侧开始)不受信任的地址的左侧......偶尔,它们可能稍后在取证上有用,但是您无法根据它们做出任何实时决策。bc

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


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


推荐阅读