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-ADDRESSXOR-MAPPED-ADDRESS 字段
    • 把该 IP:Port 回传给客户端

客户端收到响应

客户端接收到 Binding Response,提取出 MAPPED-ADDRESS 字段:

Your public IP is: 203.0.113.88:45000

这就是客户端 在 NAT 后被映射的公网地址,可用于其他 P2P 连接(如 ICE Candidate)。

流程图(简化)

[客户端]
    |
    | Binding Request
    v
[NAT设备](修改源IP)
    |
    | UDP Packet with NAT-IP:Port
    v
[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 协助

你可能感兴趣的:(WebRTC(四):STUN协议)