# 为 Discourse Live 配置你自己的 STUN 和 TURN 服务器

**URL:** <https://meta.discourse.org/t/configure-your-own-stun-and-turn-servers-for-discourse-live/414625>\
**Category:** Integrations\
**Tags:** live\
**Created:** [2026 年10 月 13 日 22:44 UTC](https://meta.discourse.org/t/configure-your-own-stun-and-turn-servers-for-discourse-live/414625 "2026-10-13T22:44:52Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

作者： ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)\
发布日期： [2026 年10 月 13 日 22:44 UTC](https://meta.discourse.org/t/configure-your-own-stun-and-turn-servers-for-discourse-live/414625/1 "2026-10-13T22:44:52Z")

</div>

> ⚠ 如果您使用的是我们的托管服务，这些设置已在您的站点上预先配置好。本指南面向自行托管 Discourse 的管理员。

Discourse Live 使用 WebRTC 进行语音和视频通话。它自带公共 STUN 服务器，以帮助参与者建立直接连接。管理员可以替换这些服务器并添加 TURN，以支持那些无法建立直接连接的网络。

**对于专为您社区使用的服务器，我们建议运行 coturn 作为您的 STUN 和 TURN 服务器，并使用共享密钥身份验证用于 TURN。** 这提供了公共地址发现和中继回退功能，而无需分发永久的 TURN 密码或依赖第三方 STUN 服务器。

本指南适用于 Live 的点对点通话。使用 LiveKit 的房间则使用 LiveKit 自己的 ICE/TURN 配置。[了解有关 Live 的 LiveKit 配置](https://github.com/discourse/discourse/blob/main/plugins/live/docs/livekit.md)。

## STUN 和 TURN 的作用是什么？

- **STUN** 帮助浏览器发现其公共 IP 地址和端口，以便尝试建立直接连接。
- **TURN** 在无法建立直接连接时中继媒体流量。

获知其公共地址的浏览器可以将其作为 **server-reflexive (`srflx`) 候选地址** 提供，这使得通过家庭和办公 NAT 的直接连接成为可能。如果没有候选地址，大多数通话将回退到 TURN 中继，从而增加延迟和中继带宽。

**即使您运行 TURN，STUN 也必须保持开放。** TURN 分配响应中也包含浏览器的公共地址，但只有部分浏览器（如 Firefox）将其用作候选地址。基于 Chromium 的浏览器和 Safari 仅通过单独的 STUN Binding 请求获知其公共地址，且浏览器不会在 Binding 请求中附加凭据。如果服务器禁用 STUN（`no-stun`）或要求对其身份验证（`secure-stun`），这些浏览器将无法获得 `srflx` 候选地址，导致它们加入的所有通话都通过中继。

配置共享密钥 TURN 后，Live 允许直接连接和中继连接。 **配置 TURN 并不会强制所有通话都通过中继。** [Live 的 ICE 配置](https://github.com/discourse/discourse/blob/main/plugins/live/lib/live/ice_config.rb)。

## 1. 准备 TURN 服务器

您可以使用支持 **TURN REST API 共享密钥身份验证** 的托管 TURN 服务，或自行运行 [coturn](https://github.com/coturn/coturn)。

对于自行托管设置，请准备：

- 一台具有公共 IP 地址且拥有足够带宽用于中继通话的服务器。
- 一个主机名，例如 `turn.example.com`，直接指向该服务器。
- 防火墙允许访问其 TURN 监听器和 UDP 中继端口范围。
- 如果您提供基于 TLS 的 TURN，请准备有效的证书。

参与者的浏览器直接连接到 TURN。普通的 HTTP 反向代理或 CDN 代理无法承载 TURN 流量。

### coturn 配置示例

生成随机密钥：

```bash
openssl rand -hex 32

```

请保密该结果。您将在 coturn 和 Discourse 中输入相同的值。

在直接分配了公共 IP 的服务器上，请在 `/etc/turnserver.conf` 中使用以下内容作为起点：

```ini
listening-port=3478

fingerprint
realm=turn.example.com

use-auth-secret
static-auth-secret=REPLACE_WITH_YOUR_RANDOM_SECRET

# 不要添加 no-stun 或 secure-stun：浏览器发送不带凭据的 STUN Binding 请求，
# 许多浏览器依赖这些请求来发现其公共地址。

min-port=49152
max-port=65535

no-multicast-peers

# 此示例开始时未启用 TLS。
no-tls
no-dtls

```

替换主机名和密钥，保护配置文件，并重启 coturn。移除任何冲突的 `no-auth` 或静态 `user=` 配置。Coturn 的共享密钥模式会在内部启用所需的身份验证机制。[Coturn 配置参考](https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf)。

匿名 STUN 仅向客户端报告其自身的地址；它无法中继流量，因此不会使您的服务器变成开放中继。最近版本的 coturn 默认关闭可选的 RFC 5780 和 `MAPPED-ADDRESS` 响应属性，这使 Binding 响应接近请求大小，并限制了其用于反射攻击的实用性。请保持 `rfc5780` 和 `stun-backward-compatibility` 处于禁用状态。

允许入站流量通过：

| 端口 | 协议 | 用途 |
| --- | --- | --- |
| `3478` | UDP | STUN 和 TURN |
| `3478` | TCP | TURN |
| `49152–65535` | UDP | 中继媒体 |

同时允许相应的出站流量。中继范围必须与 `min-port` 和 `max-port` 匹配。

如果服务器位于 NAT 后面，请配置 coturn 的 `external-ip=PUBLIC_IP/PRIVATE_IP` 映射，并转发监听器和中继端口。中继端口必须通过 NAT 保留其端口号。[Coturn 部署选项](https://github.com/coturn/coturn/wiki/turnserver)。

### 为限制性网络添加 TLS

基于 TLS 的 TURN 为网络阻止 UDP 的参与者提供了另一种连接选项。

移除 `no-tls` 并配置：

```ini
tls-listening-port=5349
cert=/path/to/fullchain.pem
pkey=/path/to/privkey.pem

```

开放 `5349/TCP`，确保 coturn 可以读取证书和密钥，并在更新证书后重启。

如果 TURN 服务器上的 `443/TCP` 端口可用，您也可以使用它。这可能有助于在限制性网络中连接，尽管某些网络也会检查并阻止端口 443 上的非 HTTP 流量。当浏览器通过 TCP 或 TLS 访问 TURN 时，仍然需要 UDP 中继范围。[Coturn 服务器文档](https://github.com/coturn/coturn/wiki/turnserver)。

## 2. 配置 Discourse

在 **管理员 → 设置** 中，搜索这些 Live 设置：

| 设置 | 值 |
| --- | --- |
| `live_stun_servers` | 您的 coturn 服务器的 STUN URI — 替换默认条目 |
| `live_turn_secret` | 用于 coturn 的 `static-auth-secret` 的值 |
| `live_turn_secret_servers` | 您的 TURN URI，用 `|` 分隔 |
| `live_turn_servers` | 空 |
| `live_turn_username` | 空 |
| `live_turn_credential` | 空 |

对于上述配置，在 `live_stun_servers` 中输入以下内容：

```plaintext
stun:turn.example.com:3478

```

并在 `live_turn_secret_servers` 中输入以下内容：

```plaintext
turn:turn.example.com:3478?transport=udp|turn:turn.example.com:3478?transport=tcp

```

如果您启用了 TLS，请添加其端点：

```plaintext
turn:turn.example.com:3478?transport=udp|turn:turn.example.com:3478?transport=tcp|turns:turn.example.com:5349?transport=tcp

```

使用 `stun:`、`turn:` 和 `turns:` URI，不带 `//`。仅列出您的服务器实际支持的端点。

基于 Chromium 的浏览器也会向您列出的 TURN 服务器发送 STUN 请求，因此只要 coturn 应答匿名 STUN，空的 `live_stun_servers` 也可以工作。显式列出 STUN URI 使设置更清晰，涵盖其他浏览器，并允许 Live 的连接诊断独立测试它。

`live_turn_secret_servers` 列表使用从共享密钥生成的凭据。单独的 `live_turn_servers` 列表使用固定的用户名和密码。[Live 设置定义](https://github.com/discourse/discourse/blob/main/plugins/live/config/locales/server.en.yml)。

保存设置，然后让参与者退出并重新加入通话以获取新配置。

## 3. 验证设置

测试来自不同网络的两个参与者，例如家庭宽带和移动数据，并在 **多个浏览器** 中测试 — 至少一个基于 Chromium 的浏览器和 Firefox。确认双向音频正常工作，然后测试视频和屏幕共享。

在点对点房间内，打开房间的 **⋮** 菜单并选择 **连接诊断** ：

- 在 **STUN/TURN 服务器** 下，每个服务器应显示 **可达** 。TURN 服务器应列出 **中继地址** ，UDP 服务器应列出 **公共地址** 。“公共地址：无”表示 STUN 请求未得到应答 — 请检查 `no-stun`/`secure-stun` 以及 `3478/UDP` 是否开放。
- 在 **对等方** 下，路由显示每个连接如何传输媒体： **直接（同一网络）** 、 **直接（通过 STUN 穿越 NAT）** 或 **通过 TURN 中继** 。大多数普通家庭网络中的参与者应直接连接。
- **复制报告** 生成一份文本报告，您可以与 troubleshooting 人员分享。该报告包含参与者的 IP 地址，请私下分享。

在 Chromium 浏览器中，`chrome://webrtc-internals` 以更低级别显示相同细节：

- `srflx` 候选地址代表已发现的公共地址。
- `relay` 候选地址代表可用的 TURN 中继。
- 选定的候选地址对显示实际传输媒体的连接。

**成功的直接通话并不能证明中继功能正常。** 还请从需要 TURN 的网络进行测试，或使用具有 `iceTransportPolicy: "relay"` 和临时凭据的 WebRTC 测试客户端。

检查 coturn 日志中的成功已验证分配。无效凭据的请求不得获得中继分配。初始的 `401` 身份验证质询是正常的；重复的身份验证失败需要调查。

## 保持服务器专用于您的社区

共享密钥保留在 Discourse 和 TURN 服务器上。参与者接收临时凭据。Live 目前生成有效期为 12 小时的凭据以创建分配；已建立的分配可以在刷新时继续。[Live 的凭据生成](https://github.com/discourse/discourse/blob/main/plugins/live/lib/live/ice_config.rb)。

这防止了匿名开放中继，但 TURN 凭据不与浏览器来源绑定：参与者可以复制并重复使用其临时凭据。为了限制滥用：

- 将 Live 访问限制在预期组内。
- 监控中继带宽和分配计数。
- 设置适合您社区的 coturn 分配配额和带宽限制。
- 阻止从中继访问从 TURN 主机可达的私有、链路本地和其他内部目标。
- 保持 coturn 更新，如果共享密钥泄露，请轮换它。

为此 Discourse 部署使用专用密钥。您的服务器还将应答来自任何人的匿名 STUN 请求；这是预期的，使用很少带宽，且不授予中继访问权限。[Coturn 身份验证和访问控制](https://github.com/coturn/coturn/blob/master/README.turnserver)。

## 替代方案

### 仅替换公共 STUN 服务器

将 `live_stun_servers` 设置为您自己的 STUN URI，用 `|` 分隔：

```plaintext
stun:stun.example.com:3478

```

如果您不需要中继，请保持 TURN 设置为空。仅 STUN 无法在所有网络上使通话工作。

### 使用固定用户名和密码的 TURN

如果您的提供商不支持共享密钥身份验证，请配置 `live_turn_servers`、`live_turn_username` 和 `live_turn_credential`。保持共享密钥设置为空。

参与者接收这些固定凭据，这使得它们更容易在您站点之外重复使用。此外，当配置了静态 TURN 服务器且 STUN 列表为空时，Live 目前会强制中继连接。如果您的提供商支持，请优先使用共享密钥身份验证。[Live 的 ICE 配置](https://github.com/discourse/discourse/blob/main/plugins/live/lib/live/ice_config.rb)。

---

_[View the full topic](https://meta.discourse.org/t/configure-your-own-stun-and-turn-servers-for-discourse-live/414625)._
