# 处理终端用户真实IP的“信任链”

**URL:** <https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372>\
**Category:** Self-Hosting\
**Tags:** docker, how-to\
**Created:** [2026年六月29日 16:57 UTC](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372 "2026-06-29T16:57:59Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)\
**Post date:** [2026年六月29日 16:57 UTC](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372/1 "2026-06-29T16:57:59Z")

</div>

## 背景

Discourse 需要能够识别最终用户的真实 IP 地址。

然而，由于始终存在一个或多个上游 Web 服务器（运行在 Discourse 容器中的 nginx），最终用户从不直接连接到 Discourse。因此，我们需要一种以可信的方式将该信息传递给 Discourse 的方法。

`x-forwarded-for` 头信息就是解决方案。在本主题中，我将描述正确处理该信息的具体机制，以及我们期望它是如何传播的。

## 模板

用于信任上游代理的各种模板（例如 `cloudflare.template.yml` 或 `fastly.template.yml`）已更新为在 outlets 中使用可预测的文件名，而不是依赖文本替换（这种方式容易出错）。

## 文件名

### `server/real-ip-header.conf`

此文件包含运行在容器中的 nginx 将用作真实来源的头信息，例如：

```plaintext
real_ip_header x-forwarded-for;

```

或者在 Cloudflare 模板中设置的：

```plaintext
real_ip_header cf-connecting-ip;

```

### `server/real-ip-recursive.conf`

如果此文件存在，它将控制“真实 IP”头信息的递归处理。如果在 _Discourse 容器_ 前面有多个代理，则需要启用此功能。

```plaintext
real_ip_recursive on;

```

**示例** ：

Cloudflare → 负载均衡器 → Discourse 容器（即 nginx + Discourse 本身）

在此设置下，nginx 将收到如下所示的 `x-forwarded-for`：

```plaintext
x-forwarded-for: real_end_user_ip, cloudflare_ip

```

来自负载均衡器 IP 的连接。

为了处理这种情况，首先 nginx 确定连接的源地址（负载均衡器 IP）是否可信（参见 `set_real_ip_from`），如果是，则处理 `x-forwarded-for` 头信息中的最后一个 IP。

由于该 IP 地址是 `cloudflare_ip`，nginx 需要再次执行此操作，检查 `cloudflare_ip` 是否可信，并使用下一个 IP 地址 `real_end_user_ip`。

### `server/set-real-ip-from-ENVIRONMENT.conf`

此文件包含告诉 nginx 哪些 IP 地址可信的指令，我们可以根据需要添加尽可能多的文件和指令。

`discourse_docker` 中的模板会根据需要创建这些文件（例如 `set-real-ip-from-cloudflare.conf`），如果你有额外需求，可以自行添加。

**示例：**

如果你在 AWS 中运行，并且在 Discourse 容器前面有一个 ALB，你可以通过将以下内容添加到你的容器定义中（根据你的环境进行调整）来添加一个额外的文件：

```yaml
run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-aws.conf
      chmod: 644
      # AWS VPC 是 10.42.0.0/16，信任来自 ALB 网络的任何连接
      contents: |
        set_real_ip_from 10.42.66.0/24;
        set_real_ip_from 10.42.67.0/24;
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
      chmod: 644
      contents: |
        real_ip_header x-forwarded-for;

```

---

_[View the full topic](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372)._
