如何为动态站点设置 AWS Cloudfront 以获取动态数量的域?

如何为动态站点设置 AWS Cloudfront 以获取动态数量的域?

设置
我们有一个类似于 webs/wix/etc 的网站管理系统,我们正尝试将其与 CloudFront 一起使用。它有以下域和子域。
- ourdomain:我们的主要网站
- admin.ourdomain:每个网站的管理界面,可通过 https 访问
- images.ourdomain:S3 存储桶
- router.ourdomain:见下文
- [customersomething].ourdomain:免费用户的子域
- [customersomething.com]:高级客户的域

该系统的工作方式是,大多数域名都通过 CNAME 关联到 router.ourdomain(因为对于拥有不同域名注册商等的客户来说,这是最简单的方式),并且 router.ourdomain 是我们的 ELB 的 A 别名,然后我们 EC2 上的 PHP 根据 HTTP_HOST 值处理站点,而图像来自 S3。

我们的计划
现在我们想把这整件事放在 CloudFront 后面。大部分事情都是微不足道的。很容易把 S3 放在 CF 后面。很容易通过 asset.ourdomain 子域把每个 ourdomain/*.(js|css) 放在 CF 后面。我们可以使用 *.images.ourdomain 在子域之间动态分片,减少客户端加载时间等等,这真是一件令人高兴的事。我们甚至可以通过将“*.ourdomain”放入 CF 参数中,把每个 *.ourdomain 内容(包括动态 PHP 免费网站)放在 CF 后面。

问题
但是我们无法弄清楚的一件事是如何将所有动态创建的带有自定义域的 PHP 站点放在 CF 后面。提醒一下:这些是 CNAME-d 到 router.ourdomain。将每个域放入 CF 参数不是一个选择,因为我们需要能够处理数万个域名,并且我们需要在不为每个域名进行手动配置的情况下做到这一点。

因此我们的想法是,我们应该将 router.ourdomain 作为备用域名放入 CF 配置中,将 router.ourdomain 指向路由 53 中的 CF,并将 CF 指向我们的 ELB 作为原点。我们发现这是一种每次都收到此消息的好方法:“错误请求无法满足。错误请求。由 cloudfront (CloudFront) 生成”。实际上并非每一个时间,作为万维网.ourdomain 工作正常(它被 CNAME 到 router.ourdomain),但其他所有子域名都出现上述错误(*.ourdomain 被 CNAME 到 router.ourdomain,但即使是那些逐个被 CNAME 到 router.ourdomain 的子域名也会出现同样的错误,除了 www,当然还有 router)。所以现在我们不仅不知道该如何解决这个问题,我们甚至不明白,为什么它对 www 有效,而对其他所有域名都无效,反之亦然。

任何想法和意见都将受到赞赏,谢谢。

答案1

提醒一下:这些是 CNAME-d 到 router.ourdomain

是的,你提到了这一点。事情是这样的:

没关系。

是的,CloudFront 将备用主机名称为 CNAME。是的,CNAME DNS 记录是将给定站点的流量路由到 CloudFront 的典型方式。但不,将主机名配置为指向 CloudFront 分发的 CNAME 与现在 Cloudfront 或 HTTP 的运行无关。

当浏览器想要连接到 Web 服务器时,它会从 DNS 中查找 IP 地址。如果路径中有 CNAME,则该信息将被丢弃。浏览器关心的只是“我要连接到哪个 IP 地址?”

假设 www.example.org 是 webfarm.example.com 的 CNAME。浏览器查找 www.example.org 并最终找到 webfarm.example.com 的 IP 地址。

得到答案后,浏览器与网络服务器建立连接并发送请求。

GET / HTTP/1.1
Host: www.example.com

浏览器发送的 http 请求中的标Host:头包含地址栏中显示的主机名。CNAME 信息对于浏览器或 Web 服务器而言是完全不可用且未知的。

那么 CNAME 与请求解析和第 7 层路由有什么关系呢?不可能。CNAME 目标仅用作查找要连接的 IP 地址的路径。

您的发行版并不是在 Cloudfront 上使用这些 IP 地址的唯一发行版。还有数百或数千个其他发行版。这取决于标Host:头。

“CNAME”(备用主机名)列表是 CloudFront 在传入Host:标头中匹配的一组主机名,用于确定请求是否应被视为属于你的Host:分布。它是浏览器可能发送的标头列表。Host:在标头与分布中的配置值匹配之前,与该请求相关的分布是未知且未定义的。

如果 Cloudfront 无法将传入Host:标头与任何分布匹配,它会怎么做?

HTTP/1.1 400 Bad Request

因此,您看到的行为是预期的,也是正确的。在 CloudFront 配置中,通配符确实有效,只要它们构成备用主机名配置行中唯一的最左边元素即可。但这与 DNS 无关。

如果您希望其他客户拥有的域名能够加入您的分发,那么您就无法避免在 CloudFront 中配置它们。

但是,您可以通过 API 以编程方式修改它们,而不是手动修改:

http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/PutConfig.html

每个分发最多有 100 个这样的别名,但您可以通过向 AWS 支持提交表单来请求增加别名数量。但事实上,将它们分成多个分发也同样有用,因为如果您将主机标头转发到原始服务器(如果原始服务器能够分辨出差异,您必须这样做),CloudFront 不会将对象缓存在请求源中的一个主机的给定路径上,并将其作为不同主机的缓存响应返回,即使在同一个分发中也是如此。它不能,因为请求中的一个重要参数已从一个请求更改为另一个请求。

相关内容