如何通过CloudFront获取请求的客户端IP?

时间:2018-07-18 04:51:00

标签: amazon-cloudfront

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

严厉吗?那我该如何获得真实的客户端IP?

2 个答案:

答案 0 :(得分:7)

  

对吗?

不完全是。

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

只要e在CloudFront address ranges中,您就可以信任并删除它。

剩下d作为客户地址。

在此示例中,值abc几乎没有价值,因为您不信任它们的真实性,因为它们对于第一个(从右)不信任地址的左侧...有时,它们可能在法庭上有用,稍后,但是您不能基于它们做出任何实时决策。

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


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

答案 1 :(得分:0)

我们可以采用的方法是使用“带有Lambda的CloudFront Edge” ,然后将最后一个IP复制到不同的标头中(例如, My-X-Forwarded-For >),然后将此标头替代项复制到应用服务器之前的层中的 X-Forwarded-For

让我们说,交通流量不足

Client sends => CloudFront => ALB => WebServer => AppServer

CloudFront Edge必须注入具有来自X-Forwarded-For的最正确IP的新标头 My-X-Forwarded-For WebServer 将具有标头规则,以使用 My-X-Forwarded-For

中的值覆盖 X-Forwarded-For 标头

这对应用程序层透明。 基础架构中出现的基础架构问题。由于我们引入了AWS CloudFront层,因此无需在应用程序层进行更改。