WebRTC(四):STUN协议

发布于:2025-06-16 ⋅ 阅读:(20) ⋅ 点赞:(0)

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 协助

网站公告

今日签到

点亮在社区的每一天
去签到