问题
正如您提到的,AWS CloudFront 使用一长串 IP 地址范围。他们的文档中提到了这一点。您可以通过这一行来查看它们(源,需要jq您可以从brewMacOs 中获得。):
curl 'https://ip-ranges.amazonaws.com/ip-ranges.json' | jq -r '.prefixes[] | select(.service=="CLOUDFRONT") | .ip_prefix'
(更新:或直接从他们的文档中提到的http://d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips。)
现在,2021 年 4 月,它给了我 122 个范围。
解决方案
您可以在 Node 中对该文件进行 AJAX 调用,解析 JSON 文件,将列表作为字符串 () 数组获取cloudFrontIps,然后将其传递给app.set('trust proxy', ['loopback', ...cloudFrontIps]).
好消息!
好消息是其他人已经做到了!检查https://github.com/nhammond101/cloudfront-ip-ranges。
最后的笔记
- 这很明显,但值得一提的是,以异步方式获取此列表!因此,您可能希望延迟(例如
await)您的应用程序启动,直到此列表可用。但这不是必须的——app.set在 HTTP 服务器启动后调用应该可以工作,认为在短时间内您将记录 CloudFront 的 IP。
- 您可能希望调用此文件并定期获取新列表。该软件包建议每 12 小时一次,使用
setTimeout.
- 我的理解是调用
app.set正在运行的服务器将使新列表立即适用于未来的调用,而无需重新启动。我对每个请求X-Forward-For的检查方式以及调用函数的方式得到了这种印象。所以,TL;DR:您不需要每 12 小时重新启动一次服务器!app.set compileTrust
app.set我查看了 express 的代码,每次调用它时似乎都会覆盖(而不是附加)列表。因此,如果您有自己的一些 IP(例如,您VPC's CIDR在 AWS ELB 中),则每次app.set在setTimeout.