WebRTC-STUN协议详解

1、STUN协议概述

STUN(Session Traversal Utilities for NAT)NAT会话穿透工具,STUN是一个Client/Server协议,支持请求/响应类型、指示类型两种类型。STUN作为ICE(Interactive Connectivity Establishment,交互式连接建立)解决方案的一种工具使用,STUN协议本身没有穿透等能力,只是为穿透提供反射地址,穿透不成功时,需要使用TURN协议。

1.1 请求/响应类型(request/response)

由客户端给服务器发送请求,并等待服务端返回响应,用于确定一个NAT给客户端分配的具体绑定。客户端通过事务ID将请求响应连接起来。

1.2 指示类型(indication transaction)

由服务器或者客户端发送指示,另一方不产生响应,用于保持绑定的激活状态。

2、STUN交互过程

2.1 交互过程

(1)在WebRTC中,STUN客户端内置在浏览器用户代理中,在会话建立之前,先发送stun测试报文,以便浏览器确定其是否位于NAT之后并发现映射地址和端口。

(2)当STUN服务器收到STUN Binding请求时,它会记录Binding请求来自哪个IP地址和端口号,此地址和端口号随后将以STUN Binding响应的形式返回客户端。(通过XOR-MAPPED-ADDRESS属性)。

(3)客户端将响应中发来的IP地址和端口与其发送的IP地址和端口进行比较,以此来判断客户端和服务器之间有没有NAT,若不同,则说明至少有一个NAT,客户端能够识别由最外层的NAT分配的IP地址和端口。存在多个NAT时,STUN只能识别最外层NAT的相关信息。

(4)STUN服务器将源传输地址复制到STUN Binding响应中XOR-MAPPED-ADDRESS属性中,并将绑定响应发送回STUN客户端。当这个数据包通过NAT返回时,NAT将修改IP报头中的目的传输地址,但是STUN响应主体中XOR-MAPPED-ADDRESS属性中的传输地址将保持不变。通过这种方式,客户端可以了解最外面的NAT相对于STUN服务器分配的反射传输地址。

2.2 保活机制

在ICE中,STUN协议用于连通性检查和ICE保活,客户端需要按固定间隔以指示形式发送STUN Binding请求,防止NAT映射超时,指示型请求可使NAT重置其UDP定时器,发送间隔短于NAT UDP定时器设置,就可以保持NAT映射。

2.3 身份验证机制

2.3.1 短期身份验证

短期身份验证采用用户名/密码方式,此机制适用于单个会话。ICE使用此方法对每组连接检查应用不同的身份验证。短期身份验证机制假设在STUN事务之前,客户端和服务器已经使用了其他协议来交换了证书,以username和password形式。这个证书是有时间限制的。在WebRTC中通过SDP进行相关信息的交互。

2.3.2长期身份验证

长期身份验证采用质询/响应机制,允许使用长期凭据。长期身份验证机制依赖于一个长期证书,username和password在客户端和服务器中是共用的。这个证书从它提供给用户开始将一直是有效的,直到该用户不再是该系统的用户。

3、STUN报文格式详解

3.1 STUN包头格式

STUN Message Header.png

最高两位:为0,在STUN协议与其他协议端口复用时,用于区分STUN和其他数据包,如RTP数据包。

STUN Message Type(16bits):消息类型。定义消息类型如下:

STUN Message Type.png

Message Type后14bits可进一步分解为如下结构:

Format of STUN Message Type Field.png

(1)C1-C0两位表示类编码
0b00:request
0b01:indication
0b10:success response
0b11:error response
(2)M11-M0表示方法
STUN目前定义了一个绑定方法,Binding方法可以用于请求/响应类型和指示类型。method=0b000000000001 (Binding)
  
Message Length:(16bits),消息长度,不包含STUN Header的20个字节。所有的STUN属性都是20字节对齐的。

Magic Cookie:(32bits),固定值0x2112A442,用于反射地址的异或(XOR)运算。

Transaction ID:(96bits),事务ID标识符,请求对应的响应具有相同的标识符。

3.2 STUN属性

STUN 消息头后跟着多个属性,每个属性都采用 TLV 编码,type 为 16 位的类型、lenght 为 16 位的长度、value 为属性值。每个 STUN 属性必须是 4 字节对齐。lenght 字段的值只表示 TLV 中 V(Value) 的长度,既不包括 T(Type) 和 L(length),又不包括 padding 填充数据的长度。具体如下所示:

Format of STUN Attributes.png

STUN 请求和响应都包含消息属性。消息属性分为强制理解属性和可选理解属性,具体如下所示:

STUN Attributes types.png

在ICE中,包含STUN用到的几个属性,具体如下所示:

ICE Attributes.png

MAPPED-ADDRESS:NAT客户端的反射地址,具体如下所示:

Format of MAPPED-ADDRESS Attribute.png

Family:IP类型,0x01-IPV4、0x02-IPV6
Port:端口
Address:IP地址

XOR-MAPPED-ADDRESS:与MAPPED-ADDRESS属性基本相同,区别在于反射地址经过一次异或(XOR)处理,异或运算是其自身的逆运算,客户端经过一次异或运算获得真实的反射地址。解决ALG篡改地址和端口的问题。

USERNAME:用户名,用于消息完整性,在webrtc中的规则为 “对端的ice-ufrag:自己的ice-ufrag”,其中ice-ufrag已通过提议/应答的SDP信息进行交互。

MESSAGE-INTEGRITY:STUN 消息的 HMAC-SHA1 值,长度 20 字节,用于消息完整性认证。详细的计算方式后续进行举例说明。

FINGERPRINT:指纹认证,此属性可以出现在所有的 STUN 消息中,该属性用于区分 STUN 数据包与其他协议的包。属性的值为采用 CRC32 方式计算 STUN 消息直到但不包括FINGERPRINT 属性的的结果,并与 32 位的值 0x5354554e 异或。

ERROR-CODE:属性用于error response报文中。其中包含了300-699表示的错误码,以及一个UTF-8格式的文字出错信息(Reason phrase)。

REALM:此属性可能出现在请求和响应中。在请求中表示长期资格将在认证中使用。当在错误响应中出现表示服务器希望客户使用长期资格来进行认证。

NONCE:出现在请求和响应消息中的一段字符串。

UNKNOWN-ATTRIBUTES:此属性只在错误代码为420的的错误响应中出现。

SOFTWARE:此属性用于代理发送消息时包含版本的描述。它用于客户端和服务器。它的值包括制造商和版本号。该属性对于协议的运行没有任何影响,仅为诊断和调试目的提供服务。SOFTWARE属性是个可变长度的,采用UTF-8编码的小于128个字符的序列号

ALTERNATE-SERVER:属性表示 STUN 客户可以尝试的不同的 STUN 服务器地址。属性格式与 MAPPED-ADDRESS 相同。

在Binding请求中通常需要包含一些特殊的属性,以在ICE进行连接性检查的时候提供必要信息,详细的属性如下所示:

PRIORITY 和 USE-CANDIDATE:终端必须在其request中包含PRIORITY属性,指明其优先级,优先级由公式计算而得。如果有需要也可以给出特别指定的候选(即USE-CANDIDATE属性)。

ICE-CONTROLLED和ICE-CONTROLLING: ICE流程中定义了两种角色:controlling和controlled。不同的角色在candidate pair优先级的计算,pair nominate的决策上有所不同。一般流程下,会话的双发各自的角色选择是与会话协商的流程相关的。offerer是controlling,answerer是controlled。

ICE-CONTROLLED或者是ICE-CONTROLLING,这两个属性都会携带一个Tie breaker这样的字段,其中包含 一个本机产生的随机值。收到该bind request的一方会检查这两个字段,如果和当前本机的role冲突,则检查本机的tie breaker值和消息中携带的tie breaker值进行判定本机合适的role。判定的方法为Tie breaker值大的一方为controlling。如果判定本端变更角色,这直接修改;如果判定对端变更角色,则对此bind request发送487错误响应,收到此错误响应的一方变更角色即可。

4、STUN报文示例

4.1 Binding Request

Binding Request.png

4.1.1 USENAME
USENAME 组成格式为对端ice-ufrag:自己ice-ufrag,其中对端ice-ufrag为webrtc中的answer sdp,其中属性a=ice-ufrag:2g25ql32,自己ice-ufrag为offer sdp,其中属性a=ice-ufrag:cVN4。

USENAME.png

STUN属性采用4字节对齐,不足的用00填充。

4.1.2 ICE-CONTROLLING

ICE-CONTROLLING.png

Tie breaker:64bits的随机值,用于解决角色冲突。

4.1.3 PRIORITY

PRIORITY.png

4.1.4 MESSAGE-INTEGRITY

MESSAGE-INTEGRITY.png

详细的计算过程后续进行详述。

4.1.5 FINGERPRINT

FINGERPRINT.png

输入:FINGERPRINT属性之前的STUN数据
00 01 00 50 21 12 a4 42 67 33 45 6e 4a 4b 48 56
32 43 32 7a 00 06 00 0d 32 67 32 35 71 6c 33 32
3a 63 56 4e 34 00 00 00 c0 57 00 04 00 00 03 e7
80 2a 00 08 3e e8 21 cb d9 f4 4a d7 00 24 00 04
6e 00 1e ff 00 08 00 14 ba 64 89 fa 5b 93 71 c4
d6 3d bf 20 8c a1 b2 ac 25 8b bd 75

CRC-32运算:获得以下输出
输出:0x5B6D336D

XOR运算:0x5B6D336D XOR 0x5354554E
输出:0x 08 39 66 23即FINGERPRINT的值。

4.2 Binding Response

Binding Response.png

4.2.1 XOR-MAPPED-ADDRESS

XOR-MAPPED-ADDRESS.png

Port:与Magic cookie的网络字节序前16位进行异或
0xc1a6 = 57524 XOR 0x2112
IP:与Magic cookie进行异或运算
0x8d06a50b = (172.20.1.73)XOR 0x2112a442

5、参考

https://tools.ietf.org/html/rfc3489
https://tools.ietf.org/html/rfc5389

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容