WebRTC(四):STUN协议
STUN(Session Traversal Utilities for NAT)协议是一个 网络穿透协议,主要用于在 NAT(网络地址转换) 环境中帮助终端获取自己的公网地址和 NAT 类型,以便进行 P2P通信。STUN 是 WebRTC、VoIP、SIP 等技术的核心组件之一。
本质作用
帮助客户端知道自己“在外部世界”的 IP 和端口
大多数终端处于 NAT 后面,无法直接建立 P2P 通信。STUN 协议通过与 STUN 服务器交互,帮助客户端获取 NAT 分配的公网 IP 和端口。
应用场景
- WebRTC 进行 P2P 建连前,确定 NAT 类型、公网地址
- SIP 电话通信、视频会议
- VoIP 和即时通信软件
- TURN 和 ICE 的基础协议组件
基本流程
概述
Client(NAT内) ←→ STUN Server(公网)1. 客户端发送 STUN Binding Request(UDP)
2. STUN 服务器接收后,记录源 IP+端口
3. 服务器将记录到的外部地址封装进 Binding Response 返回客户端
4. 客户端分析返回结果,得到自己 NAT 后的公网 IP:Port
客户端发送 Binding Request
客户端通过 UDP 向 STUN 服务器发送一个 Binding Request
报文,内容包括:
- 报文类型:0x0001(Binding Request)
- Transaction ID:客户端生成的随机 96 位值
- 可选属性:Username、Message-Integrity 等(用于验证)
客户端 NAT 私网地址(如 192.168.1.100:6000)↓UDP → STUN Server
NAT 转换地址
在报文到达 STUN 服务器前:
- NAT 把源地址从:
192.168.1.100:6000
改写为203.0.113.88:45000
(公网地址+端口)
STUN 服务器处理
STUN Server 接收到请求后:
- 读取 UDP 包的 源 IP 和源端口(即 NAT 映射后的公网地址)
- 构造一个
Binding Response
报文- 包含
MAPPED-ADDRESS
或XOR-MAPPED-ADDRESS
字段 - 把该 IP:Port 回传给客户端
- 包含
客户端收到响应
客户端接收到 Binding Response,提取出 MAPPED-ADDRESS
字段:
Your public IP is: 203.0.113.88:45000
这就是客户端 在 NAT 后被映射的公网地址,可用于其他 P2P 连接(如 ICE Candidate)。
流程图(简化)
[客户端]|| Binding Requestv
[NAT设备](修改源IP)|| UDP Packet with NAT-IP:Portv
[STUN Server]|| Binding Response(包含映射后的公网地址)v
[NAT设备]|v
[客户端] ← 得知自己 NAT 后公网地址
探测NAT类型
通过对多个地址的响应判断 NAT 类型:
测试序列 | 服务器行为 | 判断结果 |
---|---|---|
Test I | 原地址回复 | 无 NAT 或 Full Cone NAT |
Test II | 更换 IP 回复 | Symmetric NAT |
Test III | 同 IP 不同端口 | Port Restricted NAT |
关键字段说明
字段 | 说明 |
---|---|
MAPPED-ADDRESS | 客户端的公网地址(直接暴露) |
XOR-MAPPED-ADDRESS | 避免中间人伪造,更安全的地址返回方式 |
MESSAGE-INTEGRITY | 对报文做 HMAC-SHA1 签名 |
FINGERPRINT | 对整个包 CRC32 校验 |
报文结构
STUN 报文由以下字段组成:
报文头部(20字节)
字段 | 长度 | 说明 |
---|---|---|
Message Type | 2 字节 | 报文类型(如 Binding Request) |
Message Length | 2 字节 | 后续数据的长度 |
Magic Cookie | 4 字节 | 固定为 0x2112A442 (用于识别STUN) |
Transaction ID | 12字节 | 随机 ID,客户端生成,用于匹配请求响应 |
报文类型(Message Type)
类型名称 | 值(16位) |
---|---|
Binding Request | 0x0001 |
Binding Response | 0x0101 |
Binding Error Response | 0x0111 |
Shared Secret Request | 0x0002 |
Attribute 区域(可选)
- STUN 报文可带属性(Attribute)字段,类似 TLV 格式。
常见属性:
属性名 | 类型 | 说明 |
---|---|---|
MAPPED-ADDRESS | 0x0001 | STUN 服务器看到的外部地址 |
XOR-MAPPED-ADDRESS | 0x0020 | 安全性更高,避免中间人攻击 |
USERNAME | 0x0006 | 用户认证 |
MESSAGE-INTEGRITY | 0x0008 | 消息完整性校验(HMAC) |
ERROR-CODE | 0x0009 | 错误信息 |
FINGERPRINT | 0x8028 | CRC32 校验 |
示例
[Message Type: 0x0001]
[Message Length: N]
[Magic Cookie: 0x2112A442]
[Transaction ID: 96bit 随机值]
[Attributes...]
安全机制
- 使用 MESSAGE-INTEGRITY 字段 + 密钥做 HMAC-SHA1 校验
- 防止伪造和篡改
- 可配合 USERNAME/PASSWORD 做身份认证(STUN Long-Term Credential)
STUN 在 ICE 中的角色
ICE(Interactive Connectivity Establishment)是 WebRTC 用来穿透 NAT、建立 P2P 的整体方案。
- STUN 用于收集候选地址(candidate)
- 收集:
- 主机候选(Host)
- Server Reflexive 候选(通过 STUN 得到)
- Relay 候选(通过 TURN 得到)
- 然后由 ICE 做候选优先级、连接尝试和建立
STUN命令
示例:使用 stun
命令查看 NAT 类型(Linux)
sudo apt install stun
stun stun.l.google.com:19302# 输出
STUN client version 0.97
Primary: Open NAT, External IP: 203.0.113.45:45678
总结
关键点 | 描述 |
---|---|
功能 | 获取 NAT 后公网地址,辅助 P2P 穿透 |
协议类型 | UDP,轻量快速 |
标准文档 | RFC 5389 |
应用 | WebRTC, SIP, VoIP, ICE |
安全 | 支持身份验证和消息完整性验证 |
局限 | 无法穿透 Symmetric NAT,需 TURN 协助 |