全站 CDN 使用 AWS CloudFront

大家好。我最近使用 AWS CloudFront (CF) 设置了 Discourse,以实现全站加速——并使用 CF 中的 AWS 证书进行 SSL 卸载。请注意,此设置在 CDN 和 SSL 配置方面偏离了官方指南——这可能存在争议并导致未来的支持问题。所以请注意……这里有风险。我在这里分享了适合我的配置:

  1. 将 Discourse 设置为仅监听端口 80,并通过注释掉 app.yml 中的指定行来禁用 Let’s Encrypt:

  2. 将 Discourse 设置为关注 CF 标头 cloudfront-forwarded-proto,而不是 x-forwarded-proto(CF 不会传递它——而且奇怪的是无法配置为传递给源……真糟糕!:angry:

  3. 使用您打算使用的公共主机名(例如 forum.example.com)的 CNAME 设置您的 CF 分配,并使用 AWS ACM 证书(您已生成)。

  4. 使用托管 Discourse 的 EC2 服务器的公共弹性 IP(例如 ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com)设置 CF 源。将其配置为仅限 HTTP(即仅端口 80 - 无 443)。您无需在 DNS 中为源设置 fancy 主机名,如 forum-origin.example.com。EC2 主机名或 IP 即可正常工作。

  5. 为不同的请求路径设置 CF“行为”。关键在于为明显是静态资源的配置缓存行为;并为所有其他内容配置不缓存(即,这些请求按原样传递给源,不进行缓存)。另一个关键点是最后一个传递规则(“默认”)使用自定义“源请求策略”,该策略除了 CF cloudfront-forwarded-proto 标头外,还将所有原始标头传递给源。还在您的行为中配置 HTTP 到 HTTPS 重定向——以便 CF 将所有最终用户请求强制为 HTTPS。

  6. 不要配置“DISCOURSE_CDN_URL”

  7. 启用“强制 HTTPS”

  8. 不要配置“长轮询基础 URL”——将其留空。尽管有关于将其通过代理传递会很麻烦的严厉警告,但到目前为止它对我来说工作得很好。也许 CF 的默认保持连接时间足够长,可以防止连接中断。

我想这就是全部……:thinking:

最终结果是,所有请求,包括 HTTP/文档、所有支持的静态资源、所有 AJAX 调用等,都由同一个域名(例如 forum.example.com)提供服务。缓存行为(和传递行为)由您在 CF 中配置的“行为”决定。所有连接都使用终止于 CF 边缘的 AWS ACM 证书进行加密——然后将未加密/HTTP 流量发送回源服务器。

我敢说这可能比 meta.discourse.org 目前的做法更干净:shushing_face:。

7 个赞

您好 @jaffadog

我遇到了类似的情况,但使用的是完全的站点和不同的 CDN。在您的实验中,您是否测试过使用网站域名 URL 配置 DISCOURSE_CDN_URL?例如,在完全 CDN 模式下,如果您的网站 URL 是 https://foo.bar.com;那么 CDN URL 也应该是 https://foo.bar.com。如果我们留空 DISCOURSE_CDN_URL,那么网站资源的 URL 将以相对路径开头。例如,如下代码片段:

      <link rel="preload" href="/extra-locales/admin?v=8f522e122c802d1ed66dfa7fecafbb35" as="script">
<script defer src="/extra-locales/admin?v=8f522e122c802d1ed66dfa7fecafbb35"></script>

虽然这两个 URL 都请求 https://foo.bar.com,但这在生产网站上看起来并不优雅。