WebRTC 网络穿透技术:STUN、TURN 与 ICE 协议详解
WebRTC(Web Real-Time Communication)是一种支持浏览器之间进行实时音视频通信的技术。然而,在复杂的网络环境中,两个设备可能位于防火墙或 NAT 之后,无法直接建立点对点连接。为了解决这个问题,WebRTC 依赖于一套网络穿透协议,主要包括 STUN、TURN 和 ICE。
1. 问题背景:NAT 与防火墙的挑战
在深入协议之前,必须先理解障碍是什么:
- NAT(网络地址转换): 将私有网络内的多个设备映射到一个公网 IP 地址上。外部网络无法直接访问 NAT 后的设备,因为其私有 IP 在公网无效。
- 防火墙: 根据安全策略,有选择地阻止或允许网络流量。
这导致了一个核心问题:两个浏览器分别位于公司内网 A 和家庭内网 B 中,它们不知道对方的公网可达地址,也无法直接向对方的私有 IP 地址发送数据包。
解决思路: 需要一种机制来“发现”自己在公网上的地址,并协商出最佳的连接路径。这就是 STUN、TURN 和 ICE 的职责。
2. STUN(Session Traversal Utilities for NAT)
目标:帮助设备发现其位于公网上的 IP 地址和端口。
工作原理:
- STUN 客户端: 你的浏览器应用程序。
- STUN 服务器: 一个部署在公网上的、简单的 UDP 服务器(通常由服务提供商或应用程序提供商部署)。
工作流程:
- 请求: 浏览器(STUN 客户端)向公网的 STUN 服务器发送一个请求:“我的地址是什么?”。
- 响应: STUN 服务器接收到这个请求包,查看数据包的源 IP 地址和源端口,然后将这两个信息填入响应包,发回给客户端。
- 获知公网映射: 客户端收到响应后,就知道了“在公网看来,我的地址是
[服务器看到的 IP] : [服务器看到的端口]”。这个地址被称为 服务器反射地址。
关键点:
- STUN 协议本身非常简单,只做地址发现。
- 它不适用于所有类型的 NAT(例如,对称型 NAT 会导致问题,因为映射的端口是随目标地址变化的)。
- 它不中转媒体数据,只交换控制信息。
3. TURN(Traversal Using Relays around NAT)
目标: 当直接的点对点连接(通过 STUN 发现的方法)因严格 NAT 或防火墙策略而失败时,作为“中继”或“备胎”来传输音视频数据。
工作原理:
- TURN 客户端: 你的浏览器。
- TURN 服务器: 一个部署在公网上的、功能更强的服务器,具有公网 IP 和中继能力。
工作流程:
- 分配中继地址: 浏览器通过 TURN 协议,向 TURN 服务器申请一个中继地址(一个公网 IP 和端口)。
- 数据转发: 浏览器告诉对端:“请把媒体流发送到我这个中继地址”。对端发送数据到 TURN 服务器的这个中继地址,TURN 服务器再将数据“转发”给浏览器。反之亦然。
- 角色: TURN 服务器是所有流量的中转站。
关键点:
- TURN 是可靠的“终极方案”,能穿透任何网络环境。
- 缺点是性能成本高:所有数据都要经过服务器中转,增加延迟和带宽成本。
- 安全与权限: TURN 协议包含认证机制,防止未经授权的设备滥用中继资源。
4. ICE(Interactive Connectivity Establishment)
目标: ICE 不是 STUN 或 TURN 的替代品,而是一个框架和算法,用于智能地、自动地选择最佳的连接路径。它整合了 STUN 和 TURN。
核心概念:
- 候选地址: 一个可能的连接端点,由 {IP 地址, 端口, 协议类型} 组成。ICE 会收集多种候选地址。
- 候选地址类型:
- 主机候选地址: 设备本地的网络地址(如 192.168.1.100:5000)。
- 服务器反射候选地址: 通过查询 STUN 服务器获得的地址。
- 中继候选地址: 从 TURN 服务器分配到的地址。
工作流程(循序渐进):
阶段一:候选地址收集
- 应用程序启动 ICE 代理。
- ICE 代理开始并行收集候选地址:
- 自动生成主机候选地址(本地所有网络接口)。
- 向配置的 STUN 服务器 发送请求,获得服务器反射候选地址。
- 向配置的 TURN 服务器 发送请求,获得中继候选地址。
阶段二:候选地址交换
3. 通过信令服务器(如 WebSocket),双方交换各自收集到的所有候选地址列表。这是一个 SDP(会话描述协议)的交换过程。
阶段三:连接性检查
4. 这是 ICE 最核心的步骤。双方在收到对方的候选地址列表后,开始配对检查。
5. 配对: 本地的每一个候选地址,与远程的每一个候选地址进行配对,形成一个“候选对”。
6. 检查: 对于每一个候选对,ICE 代理会发送一个 STUN 绑定请求 从本地候选地址发往远程候选地址。这本质上是一个握手测试:“我能用这条路走到你那里吗?”
7. 优先级排序: ICE 会根据地址类型(主机 > 服务器反射 > 中继)、网络距离等,为检查排序,优先测试更优的路径。
阶段四:路径选择与完成
8. 成功响应: 如果一条路径的检查请求收到了对方的 STUN 成功响应,证明此路径是通的。
9. 提名: 在检查过程中,会标记一个或多个成功的候选对为“有效的”。最终,双方会协商确定一个候选对作为实际传输媒体数据的路径。
10. 选择逻辑: ICE 遵循“尽可能点对点,不得已再中继”的原则:
* 如果双方都在同一内网,主机候选对 成功,延迟最低。
* 如果一方或双方在 NAT 后,服务器反射候选对 可能成功,实现点对点直连。
* 如果以上都失败(如对称 NAT 互相阻挡),中继候选对 会成功,数据通过 TURN 服务器转发。
总结与关系
- STUN 是“侦察兵”,负责探查公网出口地址。
- TURN 是“运输队”,当没有直通道路时,负责转运所有货物(数据)。
- ICE 是“总指挥官”,它派出侦察兵(STUN)探查所有可能的路线,并准备好运输队(TURN)作为后手。然后它会系统地、按优先级测试每一条可能的路线组合(主机-主机、反射-反射、反射-主机、中继-任何),最终自动选择出那条可用的、最优的路线来建立连接。
在实际的 WebRTC 应用中,开发者通常需要配置 ICE 服务器列表,这个列表里就包含了 STUN 和 TURN 服务器的地址。浏览器内部的 ICE 框架会利用这些服务器,自动完成上述复杂的穿透过程,对开发者几乎透明。