本主题是另一篇帖子 another 的配套内容,后者侧重于 Discourse 的配置。本文将介绍如何在 Discourse 之前设置 Cloudfront 分发作为反向代理。
仅当您 已经 为主机名配置了 Cloudfront 分发,并希望将子文件夹代理到 Discourse 论坛时,才需要这种组合。本指南假设读者已有在生产环境中使用 Cloudfront 的经验。
流量流向
当用户加载网站时,涉及两个网络连接。每个连接都有不同的主机名:
- 网络浏览器将向 Cloudfront 发起针对公共主机名的请求。
- 然后 Cloudfront 将向 Discourse 服务器发起针对源主机名的请求。
.───────. .───────. .─────────.
( browser )───▶( CF )───▶( discourse )
`───────' `───────' `─────────'
在我们的示例中,我们假设您的 Discourse 站点将从 https://www.example.com/forum/ 加载,使用以下配置:
| 用途 | 主机名 |
|---|---|
| 公共主机名 | www.example.com |
| 源主机名 | discourse.example.com |
Cloudfront 设置
这意味着将至少定义两个源:一个用于主站点的默认源,另一个用于 Discourse 服务器。
还将至少有两个行为,每个行为指向一个源。
默认行为和源在此处与我们的目的无关;它必须已经根据您的需要进行适当配置。Discourse 特定的源和行为应按如下方式配置。
源
Discourse 服务器的第二个源应指向源主机名。
请勿配置源路径。
协议策略应为 HTTPS,最低版本为 TLSv1。
行为
模式需要匹配子文件夹。
它应附加到如上配置的源。
它应将 HTTP 重定向到 HTTPS。
它应允许所有 HTTP 动词。
它应禁用缓存。
它应转发所有客户端标头。
配置 Lambda@edge
共享托管环境(包括 discourse.org)使用 SNI。要在 Cloudfront 中实现这一点,您需要使用 Lambda@edge 确保 Cloudfront 使用源主机名进行 SNI,而不是来自查看者请求的 Host 标头。
访问 AWS Lambda 控制台并创建一个新函数。使用 Node.js 运行时环境,并创建一个具有“基本 Lambda@Edge 权限”的新角色:
点击“创建函数”。
代码编辑器出现后,用以下代码替换示例:
exports.handler = async (event, context) => {
const request = event.Records[0].cf.request;
request.headers['x-forwarded-host'] = [{
key: 'x-forwarded-host',
value: request.headers['host'][0]['value']
}];
request.headers["host"] = [{
key: 'host',
value: request.origin.custom.domainName
}];
return request;
};
点击“部署”。
在左上角,选择 Actions → Deploy to Lambda@Edge
选择您的 Cloudfront 分发,并从列表中选择正确的行为:
如果您因任何原因需要更改,请确保先“部署”,然后在版本选项卡中“发布新版本”,然后更新您的分发以使用 Lambda 的新版本。













