为子文件夹安装配置Cloudfront反向代理

本主题是另一篇帖子 another 的配套内容,后者侧重于 Discourse 的配置。本文将介绍如何在 Discourse 之前设置 Cloudfront 分发作为反向代理。

:warning: 仅当您 已经 为主机名配置了 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 的新版本。

10 个赞