STUN工作原理

文章详细介绍了STUN协议的作用,即帮助NAT后的主机发现其公网地址,用于实现通信。内容涵盖了STUN报文格式的变化,从RFC3489到RFC5389的差异,以及WebRTC如何支持STUN,包括特定的消息类型和属性。此外,还描述了STUN的工作流程,特别是通过STUN获取NAT映射后的地址的过程。
摘要由CSDN通过智能技术生成

目录

一. 前言

二. STUN报文格式

STUN Header

RFC3489

RFC5389

STUN Message Body

RFC3489

RFC5389

三. WebRTC对STUN协议的支持

四. STUN工作流程

1. 使用STUN获取NAT映射后的地址

五. 参考资料


一. 前言

        现实网络环境中绝大多数主机都是处于 NAT 之后,对于两个处于同一内网环境的主机,它们只要知道对端的内网地址就能进行通信,而对于不在同一内网的主机,如果它们想通信,要么借助带有公网地址的主机转发,要么通过一定的手段进行 NAT 穿越。

        STUN 协议是用来 NAT 穿越的工具,它允许位于 NAT 之后的主机查找到自己 NAT 映射后的公网地址,需要通信的双方交换映射后的公网地址再进行连通性检测。

        STUN 最先在 RFC3489 中定义,英文全称是 Simple Traversal of UDP Through NAT,即用 UDP 进行 NAT 穿越,而新的 RFC5389 把 STUN 定义为 Session Traversal Utilities for NAT,即 NAT 会话传输工具,RFC3489 与 RFC5389 相比,最大的区别是后者支持 TCP 穿越。

        STUN 协议是一个 C/S 模型的协议,即一端发送请求,另一端进行响应,此外还有指示类型的消息,一端发送指示消息后,另一端不必响应。

二. STUN报文格式

RFC3489 和 RFC5389 定义的报文格式有些许差别,因此下面会分开说明。

STUN Header

RFC3489

        STUN 报文以 20 个字节的头部开始,后面跟着若干属性。

        RFC3489 STUN Header 包含三个字段(2 个字节的 STUN Message Type,2 个字节的 Message Length,16 个字节的 Transaction ID)。

STUN Message Type 的取值和对应的含义如下。

Message Type含义
0x0001绑定请求
0x0101绑定响应
0x0111绑定错误响应
0x0002共享私密请求
0x0102共享私密响应
0x0112共享私密错误响应

Message Length:STUN 报文长度(不包括固定的 20 字节的头部)。

Transaction ID:事务 ID,用于关联请求和对应的响应,同一事务的请求和响应事务 ID 相同。

RFC5389

         RFC5389 的 STUN Header 也是 20 个字节,只是 STUN Message Type 从 16bit 变成 14bit,开头的 2bit 固定为 00,Transaction ID 从 128bit 变成 96bit,减少的 32bit 变成 Magic Cookie,其值固定为 0x2112A442,使用 Magic Cookie 可以区分 STUN RFC3489 还是 RFC5389。Message Length 含义与 RFC3489 一样,表示 STUN 报文除去头部后的长度。

RFC5389 的 STUN Message Type (14bit) 可以进一步分解成以下结构。

        M11~M0 用来表示方法,RFC 规范目前只定义了一个方法:Binding,其他方法可以由使用者自行扩展。

        C1C0 表示方法的类型,对于 C1C0=0b00 表示这是一个请求,C1C0=0b01 表示指示,C1C0=0b10 表示请求成功的响应,C1C0=0b11 表示请求失败的响应。

        方法与方法的类型是正交的,即对于每一种方法,其请求,指示,请求成功响应,请求失败响应都是可能的。

STUN Message Body

        STUN 报文头部之后有 0 或多个属性,每个属性使用 TLV 编码(Type, Length, Value)。

RFC3489

Type名称说明
0x0001MAPPED-ADDRESS返回客户端NAT映射过的IP和端口
0x0002RESPONSE-ADDRESS指明对于MAPPED-ADDRESS的响应应该发送至哪里
0x0003CHANGE-REQUEST请求服务端使用不同的IP和端口发送响应
0x0004SOURCE-ADDRESS指示服务端的IP和端口
0x0005CHANGED-ADDRESSCHANGE-REQUEST的响应
0x0006USERNAME用户名,用于安全认证
0x0007PASSWORD密码,用于安全认证
0x0008MESSAGE-INTEGRITY用于消息完整性验证
0x0009ERROR-CODE错误码
0x000aUNKNOWN-ATTRIBUTES未知属性
0x000bREFLECTED-FROM拒绝

        上图表示的意思是 MAPPED-ADDRESS 这个属性一定不出现在 Binding Req 中,必须出现在 Binding Resp 中,而 RESPONSE-ADDRESS 属性可以出现在 Binding Req 中,一定不出现在其他类型的方法中。

        N/A 表示不,M 表示必须,O 表示可选,其他类型的属性以此类推。

RFC5389

Type名称说明
0x0020XOR-MAPPED-ADDRESS异或地址
0x8028FINGERPRINT 消息指纹

        RFC5389 的属性与 RFC3489 有些许不同,大部分 RFC3489 的属性在 RFC5389 中仍然能使用,此外 RFC5389 还扩展了一些属性,例如 XOR-MAPPED-ADDRESS 获取异或后的地址, FINGERPRINT 防止消息被篡改等,其他属性可查阅 RFC5389 文档,此处不过多介绍。

三. WebRTC对STUN协议的支持

        WebRTC 支持的 STUN 消息类型除了 RFC 规范提及的之外,还扩展了 GOOG Ping 的请求/响应消息。

Message Type含义
0x0001请求消息
0x0011指示消息
0x0101成功响应消息
0x0111错误响应消息
0x0200GOOG Ping 请求消息
0x0300GOOG Ping 响应消息
0x0310GOOG Ping 错误响应消息

        对于属性值,WebRTC 并没有支持 RFC 规范中提到的所有属性,支持的属性如下所示。

Type名称
0x0001MAPPED-ADDRESS
0x0006USERNAME
0x0008MESSAGE-INTEGRITY
0x0009ERROR-CODE
0x000aUNKNOWN-ATTRIBUTES
0x0014REALM
0x0015NONCE
0x0020XOR-MAPPED-ADDRESS
0x8022SOFTWARE
0x8023ALTERNATE-SERVER
0x8028FINGERPRINT
0x802FORIGIN
0xFF00RETRANSMIT-COUNT

四. STUN工作流程

1. 使用STUN获取NAT映射后的地址

        现实网络环境中大部分主机是处于 NAT 之后,即通过 ifconfig/ipconfig 查看到的是内网地址,主机访问外网时 NAT 设备会将其内网地址映射成公网地址,主机本身是无法查看某次访问外网地址 NAT 映射后的地址是多少的,但是通过 STUN 协议,主机发送 STUN binding request, 再由 STUN 服务器回复 STUN binding reponse 即可从属性拿到映射后的地址。

        webrtc.github.io 提供了一个获取服务器反射地址的页面工具,如下所示,输入 STUN 服务地址后,点击 Gather candidates 开始收集地址,type srflx 表示该地址候选项是服务器反射地址类型,即 NAT 映射后公网地址。type host 表示主机地址候选项,跟 ifconfig/ipconfig 查看到的内网地址是一样的。



        我们通过 Wireshark 抓包分析上述流程,可以看到我主机发送的是一个 RFC5389 的 STUN binding request 消息,没有携带任何属性,而 stun1.l.google.com STUN 服务器回复的是一个 RFC5389 标准的 STUN binding success reponse 消息,消息携带了一个 XOR-MAPPED-ADDRESS 属性值,属性值中包含了映射后的地址信息。

五. 参考资料

RFC 3489 - STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)

RFC 5389 - Session Traversal Utilities for NAT (STUN)

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椛茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值