将 Cloudfront IP 范围嵌入 NGINX 配置是否合理?

将 Cloudfront IP 范围嵌入 NGINX 配置是否合理?

我正在使用 CloudFront 作为我的 EC2 实例的代理,因此所有流量都首先通过 CloudFront 路由。

问题是我还需要每个对我的 EC2 实例的请求的原始客户端的 IP 地址,所以我需要检查X-Forwarded-For以找出原始 IP 地址(因为我的 EC2 收到的默认 IP 只是 CloudFront 服务器的 IP)

我发现本文讨论了在使用中间人代理(例如 CloudFront)时如何找到原始客户端 IP。

他们提出的解决方案是列出 NGINX 配置中所有 CloudFront 的边缘服务器 IP 范围,然后X-Forwarded-For从右到左读取 IP,并转发第一个不受信任的 IP 地址(NGINX 配置中列出的 IP 地址)

这一切听起来都很好,但是如果 CloudFront 边缘服务器 IP 范围发生变化,以至于我必须更新 NGINX 配置,该怎么办?真的不想编写某种自定义脚本,不断下载其 IP 范围 JSON 文件、解析它、更新我的 NGINX 配置文件,并在 NGINX 发生更改时重新启动它。这似乎需要做很多工作,而且可能存在故障点。

我想如果我相对保证这些 CloudFront IP 范围很少会改变(比如,可能每 5 年左右才改变一次),那么这不会是什么大问题,但我找不到是否存在这样的保证,或者有任何个人报告他们有这样的经验。

这种情况该如何处理?

答案1

随着新边缘位置的添加,CloudFront IP 会定期更改,因此您不能依赖它是静态的。

我认为这里的关键是阻止除 CloudFront 之外的所有内容访问服务器,这可以使用所述标头来完成这里。基本上,CloudFront 会添加一个标头,如果标头不存在,Nginx 就不会处理该请求。您应该为您的家庭/工作 IP 地址设置例外。

鉴于到达您服务器的所有内容都是通过 CloudFront,因此使用以下方法可能会保证可靠性。

set_real_ip_from 0.0.0.0/0;

CloudFront添加标题X-转发-对于。

答案2

我在使用 Cloudfront 和 Elastic 负载均衡器的 Rails 应用中遇到了根据 X-Forwarded-For 标头确定远程 IP 的问题。收到的 X-Forwarded-For 标头看起来像 A、B、C,其中 A 是客户端 IP,B 是 Cloudfront IP,C 是 ELB IP。令我惊讶的是,Rails 返回 B 作为 remote_ip,而不是最左边的 IP A。

仔细阅读细节,实际上很明显,黑客可以发送任何 X-Forwarded-For 标头(称为欺骗),因此如果您使用 IP 进行速率限制或访问授权等安全措施,最左边的方法并不安全。如果您不关心这一点,您可以使用它,但我不推荐它。

Rails 采用的方法与您描述的 Nginx 配置相同;您必须指定受信任代理(范围),即所有 Cloudfront IP 范围。这是(不幸的是)正确且最安全的方法,但正如您已经提到的,它需要解析https://ip-ranges.amazonaws.com/ip-ranges.jsonCLOUDFRONT 前缀的文件,可随时更新。您可以订阅更改通知,检查https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html

我发现人们使用的另一种解决方案是从右侧取第 N 个 IP,在我的情况下,这将是第三个,因为我使用两个代理。如果您的流量始终通过您信任的相同代理,则 X-Forwarded-For 标头中的 IP 数量应该相同。不确定您是否可以在 Nginx 中(轻松)配置此功能,但如果可以,它将使您免于使用 Cloudfront 中的所有 IP 地址更新配置。

相关内容