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

may*_*ree 5 amazon-cloudfront

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

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

Mic*_*bot 11

这样对吗?

不完全是。

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

如果客户端(建立与CloudFront的连接的计算机)的X-Forwarded-For请求中包含标头,则该标头可能是伪造的,或者如果客户端是代理服务器,则该标头可能是合法的,但是您很少有办法知道...因此,无论哪种方式,您都应该将其视为潜在有价值的内容,但严格来说是非权威的。

最右边的值(也可能是唯一的值)是您可以信任的来自CloudFront的请求中的唯一值。

一般而言,从右边进行解析,您已知的并且可以信任的能够正确识别其上游客户端的任何地址都可以从列表中删除...但是一旦遇到第一个不受信任的地址(从右到左),您就可以使用该地址正在寻找,因为该地址左侧的任何内容都不受信任。

这意味着,如果在你的栈组件-比如应用负载平衡器或Web服务器也加入X-Forwarded-For,那么你就需要考虑什么这些组件添加到值的右侧,修改CloudFront的已提供什么。

例如。客户发送:

X-Forwarded-For: a, b, c
Run Code Online (Sandbox Code Playgroud)

CloudFront添加客户端的IP d

X-Forwarded-For: a, b, c, d
Run Code Online (Sandbox Code Playgroud)

ALB收到来自CloudFront的请求,因此添加了CloudFront出口地址e

X-Forwarded-For: a, b, c, d, e
Run Code Online (Sandbox Code Playgroud)

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

X-Forwarded-For: a, b, c, d, e, f
Run Code Online (Sandbox Code Playgroud)

f只要平衡器子网的CIDR范围是您可以信任和删除。

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

这样就剩下您d作为客户地址了。

abc几乎一文不值,在这个例子中,因为这是因为它们的第一左(右)不可信地址你不能信任其真实性......偶尔,他们可能是有用的取证,之后,但您不能基于这些信息做出任何实时决策。

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


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