大家好,欢迎来到IT知识分享网。
如果一台主机处于NAT后面,那么在一定条件下两台主机无法之间进行通讯。在这种条件下,那么使用中继服务提供通讯是有必要的,RFC5766规范定义了一个名为TURN(使用中继穿越NAT)的协议,它允许一台主机使用中继服务与对端进行报文传输。TURN不同于其它中继协议在于它允许客户机使用一个中继地址与多个对端同时进行通讯。
TURN协议也是ICE(交互式连接建立)协议的组成部分,也可以单独使用。
1、简介
2、功能一览
Peer A Server-Reflexive +---------+ Transport Address | | 192.0.2.150:32102 | | | /| | TURN | / ^| Peer A | Client's Server | / || | Host Transport Transport | // || | Address Address | // |+---------+ 10.1.1.2:49721 192.0.2.15:3478 |+-+ // Peer A | | ||N| / Host Transport | +-+ | ||A|/ Address | | | | v|T| 192.168.100.2:49582 | | | | /+-+ +---------+| | | |+---------+ / +---------+ | || |N| || | // | | | TURN |v | | v| TURN |/ | | | Client |----|A|----------| Server |------------------| Peer B | | | | |^ | |^ ^| | | | |T|| | || || | +---------+ | || +---------+| |+---------+ | || | | | || | | +-+| | | | | | | | | Client's | Peer B Server-Reflexive Relayed Transport Transport Address Transport Address Address 192.0.2.1:7000 192.0.2.15:50000 192.0.2.210:49191 Figure 1
图1
举例:在上图示例中,向PeerA发送数据时,在client必须指定192.0.2.150:32102 (Peer A’s server-reflexive transport address),而不是192.168.100.2:49582 (Peer A’s host transport address)。在server端,每个allocation都能够关联一个单独client,这样能保证relayed transport address收到数据后只会被传送给对应的client。
client可以同事拥有多个allocation在服务端。
2.1传输方式
TURN,在本文的定义中,server与peer间总是使用UDP通讯。然而,client与server间可以使用UDP,TCP,TLS任何一种协议。
+----------------------------+---------------------+ | TURN client to TURN server | TURN server to peer | +----------------------------+---------------------+ | UDP | UDP | | TCP | UDP | | TLS over TCP | UDP | +----------------------------+---------------------+
2.2 Allocations
TURN TURN Peer Peer client server A B |-- Allocate request --------------->| | | | | | | |<--------------- Allocate failure --| | | | (401 Unauthorized) | | | | | | | |-- Allocate request --------------->| | | | | | | |<---------- Allocate success resp --| | | | (192.0.2.15:50000) | | | // // // // | | | | |-- Refresh request ---------------->| | | | | | | |<----------- Refresh success resp --| | | | | | |
图2
2.3 Permissions (许可)
2.4 传输机制
TURN TURN Peer Peer client server A B | | | | |-- CreatePermission req (Peer A) -->| | | |<-- CreatePermission success resp --| | | | | | | |--- Send ind (Peer A)-------------->| | | | |=== data ===>| | | | | | | |<== data ====| | |<-------------- Data ind (Peer A) --| | | | | | | | | | | |--- Send ind (Peer B)-------------->| | | | | dropped | | | | | | | |<== data ==================| | dropped | | | | | | | Figure 3
图3
图3中,client已经创建好了allocation。首先client发送CreatePermission请求在XOR-PEER-ADDRESS属性中携带PeerA的NAT地址进行许可创建。如果这一步未完成,则无法进行中继。然后client通过Send信令发送数据给server,server中继给PeerA。当server中继地址收到PeerA的UDP报文后,将其转化为Data信令中继给client。最后,client相应中继给PeerB,但是之前没有安装许可因此server将其丢弃,PeerB发送给中继地址的UDP报文也同样被丢弃。
2.5 Channels(通道)
TURN TURN Peer Peer client server A B | | | | |-- ChannelBind req ---------------->| | | | (Peer A to 0x4001) | | | | | | | |<---------- ChannelBind succ resp --| | | | | | | |-- [0x4001] data ------------------>| | | | |=== data ===>| | | | | | | |<== data ====| | |<------------------ [0x4001] data --| | | | | | | |--- Send ind (Peer A)-------------->| | | | |=== data ===>| | | | | | | |<== data ====| | |<------------------ [0x4001] data --| | | | | | | Figure 4
图4
2.6 TURN Server的限制
2.7 避免IP分片
在某些特殊因素的应用中,尤其是某些需要发送大量数据的情况需要避免数据被IP分片。如果使用TCP协议可以忽略这点,因为在标准的TCP协议中已经考虑IP分片的因素。但是如果使用UDP协议,必须要考虑避免IP分片。
有以下两种避免IP分片的方法:
第一种:避免IP片方法是避免client和peer直接传输大量的应用数据,这种方法比较适用于VoIP这种音频数据,IP报文的长度最后不要超过576字节。这个方案需要首先考虑传输方式是TCP,UDP还是TLS,然后是使用Send/Data信令还是ChannelData消息进行数据传输。另一个因素是很难处理的,例如使用IP隧道技术时很难处理路径MTU逐渐减少的情况。
作一个参考,(client到server)的应用数据和(server到peer)的UDP报文的最大长度最多500字节,为了进一步减少IP分片的情况,优先使用ChannelData消息,因为其更为节省字节。
第二种:client和peer各种使用路径MTU发现机制来决定其应用程序数据的大小上限。
不幸的是,由于TURN server无法对ICMP进行中继,因此经典的路径MTU发现机制(RFC1191)无法解决client到peer的路径MTU发现。因此client和peer无法利用ICMP消息作为路径发现的原理,[RFC4821]定义路径MTU发现的算法。
具体如何使用[ rfc4821 ]算法依次仍在研究。然而,为实现这一目标的步骤,这个版本将支持dont-fragment属性。
2.8 RTP 协议支持
2.9 Server的选播发现机制
这个版本TURN协议设计了一个基于UDP协议的server发现机制。具体而言,一个TURN server可以拒绝一个Allocate请求,并且建议client尝试一个备选server。为了避免某些类型的攻击,client必须使用相同鉴权信息进行鉴权。
3 术语
4、通用行为
5、Allocations
所有TURN操作都围绕着allocations,并且TURN消息都关联了一个allocation。一个allocatoin伴随以下这些状态:
* 中继地址
* 5元组
* 鉴权信息
* 存活时间
* 许可列表
* 通道绑定列表
中继地址是server所分配的并用于server与peers进行通讯,5元组用于client和server通讯的标示。 client端是(client’s NAT内地址,server地址,传输类型),server端(client’s NAT外地址,server地址,传输类型)。中继地址和5元组都能唯一标识一个allocatoin。
鉴权信息(包括,用户名,口令,realm,nonce)被使用与校验随后的消息并且提供回应消息的完整信息。用户名、realm,nonce在Allocate请求中被确定。
nonce在存活周期内可以利用438(nonce改变)响应进行改变。注意,处于安全考虑,Nonce是realm,username,password的hash值。
存活时间是一个allocation是有效期,以秒为单位。每个Allocation和Refessh事务设置它的值。默认情况下,它的值为10分钟,但是client可以在Allocation和Refresh请求内携带一个指定值。Allocations只能用Refresh请求刷新存活时间。发送数据给peer并不代表刷新存活时间。
当allocatoin超时失效,它所伴随的状态都将被释放。
许可将在第8节进行讲解,通道将在第11节进行讲解。
6、创建Allocation
allocation是使用Allocate请求进行创建的。
6.1 发送Allocate请求
6.2 接收到Allocate请求
6.3 接收成功的回应
6.4 接收失败的回应
7、刷新Allocation
7.1 发送Refresh请求
7.2 接收Refresh请求
7.3 接收Refresh请求回应
8、Permissions(许可)
其实读到这里,基本上已经理解TURN协议了,有时间再补上。
9、创建Permission
10、发送数据方式
11、Channels
12、IP头字段
13、STUN新方法
14、Stun新属性
15、新错误码
16、示例
下图的示例都基于图1的网络环境进行展示的,请回顾图1的网络环境。
TURN TURN Peer Peer client server A B | | | | |--- Allocate request -------------->| | | | Transaction-Id=0xA56250D3F17ABEDE85 | | | SOFTWARE="Example client, version 1.03" | | | LIFETIME=3600 (1 hour) | | | | REQUESTED-TRANSPORT=17 (UDP) | | | | DONT-FRAGMENT | | | | | | | |<-- Allocate error response --------| | | | Transaction-Id=0xA56250D3F17ABEDE85 | | | SOFTWARE="Example server, version 1.17" | | | ERROR-CODE=401 (Unauthorized) | | | | REALM="example.com" | | | | NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | | | | | | |--- Allocate request -------------->| | | | Transaction-Id=0xC271E932AD7446A32C | | | SOFTWARE="Example client 1.03" | | | | LIFETIME=3600 (1 hour) | | | | REQUESTED-TRANSPORT=17 (UDP) | | | | DONT-FRAGMENT | | | | USERNAME="George" | | | | REALM="example.com" | | | | NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | | | MESSAGE-INTEGRITY=... | | | | | | | |<-- Allocate success response ------| | | | Transaction-Id=0xC271E932AD7446A32C | | | SOFTWARE="Example server, version 1.17" | | | LIFETIME=1200 (20 minutes) | | | | XOR-RELAYED-ADDRESS=192.0.2.15:50000 | | | XOR-MAPPED-ADDRESS=192.0.2.1:7000 | | | MESSAGE-INTEGRITY=... | | |
客户端选择一个本机地址用于这个TURN会话;例如使用(10.1.1.2:49721)在图1网络环境所描述的。客户发送一个Allocate请求到服务端的监听地址。并使用一个随机分配的96位事务号,并且包含到消息头格式中。客户使用SOFTWARE属性表示客户的软件信息,这里使用”Example client,version 1.03”作为示例。客户包含的LIFETIME属性值为1小时,大于服务端存活时间的默认最大值10分钟。在Allocate请求中必须包含REQUESTED-TRANSPORT属性,并且仅允许值为17,表示server到peer之间使用UDP进行通信。客户也可以包含DONT-FRAGMENT属性,因为可能想要在随后的Send indications中被使用。
服务端要求请求是被鉴权过的。然而,当服务端接受到初始Allocate请求时,会拒绝请求因为没有携带鉴权信息。根据STUN[RFC5389]定义的长期鉴权机制,服务端返回401错误的响应,并且携带REALM属性表示server的realm(在这个例子中是“example.com”),并且包含NONCE属性,也包含SOFTWARE属性表示服务端的软件信息。
客户端收到401错误需要重新发起Allocate请求,这次需要包含鉴权的属性。客户端选择一个新的事务号。客户端包含USERNAME属性并且包含401返回消息中所得到的REALM和NONCE属性,最终客户需要包含MESSAGE-INTEGRITY作为消息最后一个属性。它的值是通过加密算法(HMAC-SHA1)基于上面的几个属性和password计算得出。攻击者在没有password的条件下是无法计算出它的值的。
服务端收到携带鉴权消息的Allocate请求后,如果一切正常,就会创建allocation。服务端返回成功回应。服务端返回LIFETIME属性告诉allocation的存活时间。这里返回的是20分钟比请求时的1个小时要小。服务端返回的XOR-RELAYED-ADDRESS属性携带中继地址。XOR-MAPPED-ADDRESS属性包含了客户的NAT外地址,这个值在TURN协议没有使用,但是返回给客户。MESSAGE-INTEGRITY属性用于保证返回消息的完整性,注意返回消息中没有USERNAME,REALM,NONCE属性。还是可以包含SOFTWARE属性。
TURN TURN Peer Peer client server A B |--- CreatePermission request ------>| | | | Transaction-Id=0xE5913A8FCA277D3319 | | | XOR-PEER-ADDRESS=192.0.2.150:0 | | | | USERNAME="George" | | | | REALM="example.com" | | | | NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | | | MESSAGE-INTEGRITY=... | | | | | | | |<-- CreatePermission success resp.--| | | | Transaction-Id=0xE5913A8FCA277D3319 | | | MESSAGE-INTEGRITY=... | | |
TURN TURN Peer Peer client server A B |--- Send indication --------------->| | | | Transaction-Id=0x1278E9ACAEF7D3328 | | | XOR-PEER-ADDRESS=192.0.2.150:32102 | | | DONT-FRAGMENT | | | | DATA=... | | | | |-- UDP dgm ->| | | | data=... | | | | | | | |<- UDP dgm --| | | | data=... | | |<-- Data indication ----------------| | | | Transaction-Id=0x8231AE8F9242DA9FF287FEFF | | | XOR-PEER-ADDRESS=192.0.2.150:32102 | | | DATA=... | | |
客户使用Send indication向PeerA发送应用层数据,XOR-PEER-ADDRESS属性包含了PeerA的NAT外地址,Data属性包含应用数据。如果client在之前的Allocate请求中包含了DONT-FRAGMENT属性,server向peerA发送报文时应该设置DF标记。Send indicate不需要使用Stun定义的长期认证机制,因此是不包含MESSAGE-INTEGRITY属性。应用程序只能在应用层确保数据没有被篡改或伪造。
服务端收到客户的Send indication后,使用中继地址作为源地址向PeerA发送UDP数据报,并且确定DF标记。注意,如果没有PeerA地址的许可,那么服务端收到客户的Send indication后会丢弃报文。
PeerA发送UDP报文给服务端,服务端中继地址收到报文后,会构造Data indication,将UDP报文的源地址放到XOR-PEER-ADDRESS属性中,UDP报文数据放到DATA属性中发送给客户。
TURN TURN Peer Peer client server A B |--- ChannelBind request ----------->| | | | Transaction-Id=0x6490D3BC175AFF3D | | | CHANNEL-NUMBER=0x4000 | | | | XOR-PEER-ADDRESS=192.0.2.210:49191 | | | USERNAME="George" | | | | REALM="example.com" | | | | NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | | | MESSAGE-INTEGRITY=... | | | | | | | |<-- ChannelBind success response ---| | | | Transaction-Id=0x6490D3BC175AFF3D | | | MESSAGE-INTEGRITY=... | | |
客户发生bind请求绑定PeerB,使用一个可用的Channel号放在CHANNEL-NUMBER属性里,PeerB的地址放在XOR-PEER-ADDRESS属性里。在这里需要携带username,realm,nonce等鉴权信息。
服务端收到请求,将Channel号与PeerB绑定好,回复成功响应。
TURN TURN Peer Peer client server A B |--- ChannelData ------------------->| | | | Channel-number=0x4000 |--- UDP datagram --------->| | Data=... | Data=... | | | | | | |<-- UDP datagram ----------| | | Data=... | | |<-- ChannelData --------------------| | | | Channel-number=0x4000 | | | | Data=... | | |
现在客户发送ChannelData消息给服务端目的发网Peer B。ChannelData不是STUN消息格式,没有事务号,只有三个字段,分别是通道号,消息长度,消息。通道号就是上面所指定的值(这里0x4000)。服务端收到消息后检查下通道号,并使用UDP报文发给Peer B。
随后,Peer B发送UDP报文到服务端中继地址,服务端创建ChannelData消息发给客户,服务端上知道通道号,因为根据Peer B的地址可以查找之前绑定时的通道号,如果之前没有绑定,那么服务根据是否创建许可,如果有使用Data indication 发往客户端。
TURN TURN Peer Peer client server A B |--- Refresh request --------------->| | | | Transaction-Id=0x0864B3C27ADE9354B | | | SOFTWARE="Example client 1.03" | | | | USERNAME="George" | | | | REALM="example.com" | | | | NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | | | MESSAGE-INTEGRITY=... | | | | | | | |<-- Refresh error response ---------| | | | Transaction-Id=0x0864B3C27ADE9354B | | | SOFTWARE="Example server, version 1.17" | | | ERROR-CODE=438 (Stale Nonce) | | | | REALM="example.com" | | | | NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | | | | | | |--- Refresh request --------------->| | | | Transaction-Id=0x427BD3E625A85FC731DC4191 | | | SOFTWARE="Example client 1.03" | | | | USERNAME="George" | | | | REALM="example.com" | | | | NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | | | MESSAGE-INTEGRITY=... | | | | | | | |<-- Refresh success response -------| | | | Transaction-Id=0x427BD3E625A85FC731DC4191 | | | SOFTWARE="Example server, version 1.17" | | | LIFETIME=600 (10 minutes) | | |
这20分钟之内,客户端发起刷新请求给服务端,有时候服务端认为Nonce信息已经过期,会回应一个438端错误吗给客户端,并且携带新的nonce属性,注意nonce属性有变化,客户端需要再次使用新的nonce发起刷新,服务端收到新的刷新后回复成功响应。当然438错误不是必须的,根据服务端的策略而定。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135135.html