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

**URL:** https://meta.discourse.org/t/configure-a-cloudfront-reverse-proxy-for-a-subfolder-install/204859
**Category:** Self-Hosting
**Tags:** how-to, advanced-setup
**Created:** [2021 年9 月 30 日 11:50 UTC](https://meta.discourse.org/t/configure-a-cloudfront-reverse-proxy-for-a-subfolder-install/204859 "2021-09-30T11:50:52Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [2021 年9 月 30 日 11:50 UTC](https://meta.discourse.org/t/configure-a-cloudfront-reverse-proxy-for-a-subfolder-install/204859/1 "2021-09-30T11:50:52Z")

</div>

本主题是另一篇帖子 [another](https://meta.discourse.org/t/30507) 的配套内容，后者侧重于 Discourse 的配置。本文将介绍如何在 Discourse 之前设置 Cloudfront 分发作为反向代理。

> ⚠ 仅当您 _已经_ 为主机名配置了 Cloudfront 分发，并希望将子文件夹代理到 Discourse 论坛时，才需要这种组合。本指南假设读者已有在生产环境中使用 Cloudfront 的经验。

### 流量流向

当用户加载网站时，涉及两个网络连接。每个连接都有不同的主机名：

- 网络浏览器将向 Cloudfront 发起针对公共主机名的请求。
- 然后 Cloudfront 将向 Discourse 服务器发起针对源主机名的请求。

```plaintext
 .───────. .───────. .─────────.
( browser )───▶( CF )───▶( discourse )
 `───────' `───────' `─────────'

```

在我们的示例中，我们假设您的 Discourse 站点将从 `https://www.example.com/forum/` 加载，使用以下配置：

| 用途 | 主机名 |
| --- | --- |
| 公共主机名 | `www.example.com` |
| 源主机名 | `discourse.example.com` |

### Cloudfront 设置

这意味着将至少定义两个源：一个用于主站点的默认源，另一个用于 Discourse 服务器。

 ![image](https://global.discourse-cdn.com/meta/original/3X/9/d/9dc3483f798f00871a6f55c7c1ff53c3999f2ca7.png)

还将至少有两个行为，每个行为指向一个源。

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/9/e9c11b9fdb7b3c1a688b9e14a661a767ffeee8b9.png)

默认行为和源在此处与我们的目的无关；它必须已经根据您的需要进行适当配置。Discourse 特定的源和行为应按如下方式配置。

### 源

Discourse 服务器的第二个源应指向源主机名。

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/8/e861fb11e29fa3816e6ebd618f58ba2660cbadad.png)

请勿配置源路径。

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/1/e103324262f61fda5d169d3b3627edb4e5338d16.png)

协议策略应为 HTTPS，最低版本为 TLSv1。

 ![image](https://global.discourse-cdn.com/meta/original/3X/8/b/8b879b0301ec341696772c24ac79b33b0df96af6.png)

### 行为

模式需要匹配子文件夹。

 ![image](https://global.discourse-cdn.com/meta/original/3X/4/7/4761ce1521d0633cafebab9a992b8e9c90679316.png)

它应附加到如上配置的源。

 ![image](https://global.discourse-cdn.com/meta/original/3X/f/8/f8089466b4fa60c69f79ba0e24b9134f9545caea.png)

它应将 HTTP 重定向到 HTTPS。

 ![image](https://global.discourse-cdn.com/meta/original/3X/6/1/616ac9bdee9d558626a8ddd380995b524674e916.png)

它应允许所有 HTTP 动词。

 ![image](https://global.discourse-cdn.com/meta/original/3X/2/d/2d3aa80daedf5dd27f9030932e73e6abc0799fad.png)

它应禁用缓存。

 ![image](https://global.discourse-cdn.com/meta/original/3X/d/e/de73e65baf13d3dc2732e8569898c3ea41e7759e.png)

它应转发所有客户端标头。

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/2/e20f96d5ed81f3488fa89b7066c6f5d78f3f1dd8.png)

### 配置 Lambda@edge

共享托管环境（包括 [discourse.org](http://discourse.org)）使用 [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication)。要在 Cloudfront 中实现这一点，您需要使用 Lambda@edge 确保 Cloudfront 使用源主机名进行 SNI，而不是来自查看者请求的 `Host` 标头。

访问 AWS Lambda 控制台并创建一个新函数。使用 `Node.js` 运行时环境，并创建一个具有“基本 Lambda@Edge 权限”的新角色：

 ![Screenshot 2022-03-29 at 20.52.31](https://global.discourse-cdn.com/meta/original/3X/e/6/e6c49f5cdd1e5875dbdc81d9425db36e8cb3f28e.jpeg)

点击“创建函数”。

代码编辑器出现后，用以下代码替换示例：

```javascript
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

 ![Screenshot 2022-03-29 at 20.55.58](https://global.discourse-cdn.com/meta/original/3X/d/d/dd3f465a64f0baf8a4ff88eff27068a77b062bf7.png)

选择您的 Cloudfront 分发，并从列表中选择正确的行为：

 ![Screenshot 2022-03-29 at 20.56.13](https://global.discourse-cdn.com/meta/original/3X/6/d/6df0df257d4f684bf13292cd08d778a61d90a609.png)

如果您因任何原因需要更改，请确保先“部署”，然后在版本选项卡中“发布新版本”，然后更新您的分发以使用 Lambda 的新版本。
