为什么 CDN 只接受 DNS 请求而不接受 IP?
CloudFront 并非旨在以这种方式工作。它是一个庞大的、全球分布的系统。当您查找 CloudFront 分配的 IP 地址时,您会收到 CloudFront 期望接收流量的地址列表:
用于您的网站,并且
可能有成百上千的其他网站,并且
来自与您位于同一地理区域的浏览器
您需要一种方法来确定您希望 CloudFront 在处理您的请求时使用的哪个分发。
在 HTTP 模式下,它使用浏览器发送的 Host: HTTP 标头。在 HTTPS 模式下,这使用 TLS SNI 值和 Host: 标头。
如果您使用代理访问 CloudFront,则需要代理为 HTTP 注入 Host 标头,并为 HTTPS 正确设置 SNI。
例如,在 HAProxy 中,设置主机标头,覆盖任何已经存在的此类标头。
http-request set-header Host dzczcexample.cloudfront.net
当然,您也可以使用为您的分配配置的任一备用域名值。
对于 SNI:
backend my-cloudfront-backend
server my-cloudfront dzczcexample.cloudfront.net:443 ssl verify none sni str(dzczcexample.cloudfront.net)
(来源:https://serverfault.com/a/830327/153161)
但这只是最低基线工作配置,因为 CloudFront 具有这种简单设置忽略的功能。
如上所述,CloudFront 正在返回应用于访问 (1) 您的站点、(2) 从您所在的位置、(3) 立即访问的 IP 地址列表。地址列表可以而且会有所不同。 CloudFront 似乎能够通过修改 DNS 响应将流量从一组服务器移动到另一组服务器、从一个边缘位置移动到另一台服务器等,从而动态管理和分配其工作负载并缓解 DDoS……因此您的代理需要使用返回的多个地址,并且需要刷新其 DNS 值,以便它始终连接到 CloudFront 希望它连接的位置,以获得最佳行为和性能。
此外,不要忽视代理服务器将通过代理附近的边缘连接到 CloudFront 的事实,而不是靠近浏览器,因此这不是您在生产中经常使用的东西,尽管它绝对有一些有效的用例。 (对于某些应用程序,我已经在 CloudFront 的两侧使用 HAProxy 好几年了——其中一些现在已经被 Lambda@Edge 消除了,但我离题了)。
这是一个有线的 [奇怪?] 要求
不是真的。多年来,基于名称的虚拟主机一直是标准做法。在我看来,这几乎是历史上的意外,当您设置 Web 服务器时,它通常也会响应 Host 标头中的 IP 地址。一个配置良好的网络服务器不会这样做——如果你(网络浏览器)不知道你在请求什么主机并且只是向我的 IP 发送请求,那么我(网络服务器)应该告诉你我不知道您想从我这里得到什么,因为您很可能出于恶意原因或良性但令人讨厌的原因(扫描)或配置错误而到达。您也不希望搜索引擎蜘蛛在 IP 地址上找到您的内容。对列表不利,对 SEO 不利。