1 背景知识:
RFC 1918 为私有网络预留出了三个IP地址块,如下:
A 类:10.0.0.0~10.255.255.255
B 类:172.16.0.0~172.31.255.255
C 类:192.168.0.0~192.168.255.255
2 NAT类型分类:
*完全锥形NAT(Full
Cone NAT)
*地址限制圆锥形NAT(AddressRestricted NAT)
*端口限制圆锥形NAT(PortRestricted Cone NAT)
*对称NAT(Sysmetric NAT)
3 SIP:
SIP(Session Initiation Protocol):称为会话初始协议。SIP协议位于IP网络的应用层,在各个传输层(UDP、TCP、TLS等)之上
①用户代理:将接受到的请求或响应消息进行代理,发到SIP网络中。分为客户端代理(UAC)和服务端代理(UAS)
②代理服务器:负责转发SIP信息,添加用于路由的信息。
③重定向服务器:接受SIP请求,把请求中的源地址映射成零个或多个地址,返回给给客户机,从而使主叫可以通过新的被叫地址直接联系被叫。
④注册服务器:接受用户代理的请求,完成用户的注册信息,只充当UAS功能。
SIP无法穿越SIP信息的原因:
INVITE sip:feng@220.231.193.226 SIP/2.0Via: SIP/2.0/TCP 192.168.0.101:53166;①
Max-Forwards: 70
From: <sip:wc@220.231.193.226>;tag=maw4ERN5HCs.-zt-vyOxss.Knrnj7Gv9
To: <sip:feng@220.231.193.226>
Contact: <sip:wc@58.60.1.112:27045;transport=TCP;ob>;+sip.ice②
Call-ID: 3m-y5mKxc8ligLANWcTS1MOKah6loyHH
CSeq: 9482 INVITE
User-Agent: CSipSimple_endeavoru-15/r2272
Content-Type: application/sdp
Content-Length: 714
v=0
o=- 3592783354 3592783354 IN IP4 58.60.1.112
s=pjmedia
c=IN IP4 58.60.1.112 ③
t=0 0
m=audio 40551 RTP/AVP 99 0 8 101
c=IN IP4 58.60.1.112
a=rtcp:40552 IN IP4 58.60.1.112
*①中(红色部分)公网响应私网的请求信息发送200OK消息时,目的地址192.0.101.1是私网地址,而私网地址无法在公网上路由
4.STUN:
为了解决SIP无法在NAT穿越的问题,提出了STUN协议。
*RFC3489和RFC5389的区别:
①RFC3489中,STUN全称为:"SimpleTraversal of UDP through NAT“ RFC5389中,STUN全称为:"SessionTraversal Utilities for NAT“
②RFC3489下的STUN称为“经典的STUN”,不适合作为一个NAT穿越解决方案,因为对穿透失败情况没有做出补救措施
③RFC5389可以支持TCP上的连接。可以扩展到TURN。
*RFC3489下的端口类型检测:
在RFC3489的协议文档中提出MAPPED_ADDRESS字段,该字段返回私网地址穿越NAT连接公网地址时的映射地址对。也就是说从这个MAPPED_ADDRESS字段可以判断出某个客户端其处于什么环境中。下面对上图的检测情况进行说明:
1.进行TEST I,在TEST I 中,客户端发送一个STUN绑定请求到一个服务端,没有设置任何标记。如果有个response响应,客户端检查MAPPED-ADDRESS属性,如果地址和端口和发送请求的本地的IP和端口一样,则客户端知道其处于非NAT内。进行test II。在test II 中,客户端发送一个含有“change IP”和“change port”的绑定请求,这意味着服务器用一个IP和端口接收,用另一个IP和端口发送响应信息。
2.如果客户端接收到response,客户端知道它可以直接连接网络(或者至少是处于具有完全圆锥形NAT的防火墙后面,但不做地址转换)。如果没有响应,则客户端知道其处于一个对称的UDP防火墙中。
3.在test I测试中,如果IP和端口没有匹配响应中的MAPPED-ADDRESS属性,则客户端知道其处于NAT后。则也进行test II(用两个不同的地址,一个接收,一个返回信息)。如果接受到一个响应了,说明是全圆锥形NAT(因为任意外网的IP地址可以和NAT内部的私网地址通信)。如果没有接受到响应,又重新进行test I 测试,这里test I 连接的服务器的地址和端口和第一次使用test I的地址和端口不一样,如此时服务器返回的映射地址对和第一次test I返回的映射地址对一样,则表明其处于限制NAT类型环境中(看NAT类型分类),否则表明处于对称NAT
4.在第三步中,若返回的IP相同,则进行test III, 在test III中客户端发送一个“change port”端口,服务器接收到之后,用相同的IP,但端口不同作为响应,若客户端接收到了,说明不受端口改变影响,即为限制锥形NAT,否则为端口受限。
从STUN协议文档中,我们知道,STUN适合非对称NAT类型,若要进行对称NAT,还需要进行一些策略。
(1):A向STUN服务器发送连接B请求(这里A和B都已经向STUN服务器注册了)
(2):STUN服务器向A和B发送对方的映射地址
(3):B将A的对外地址作为目的地址发送一个Hole Punching UDP包。并使得B中的NAT网络开了一个洞,允许后续请求进入该洞
(4):A以B的外部地址为探测地址发送一个探测数据报,同样,该数据报也在A中的NAT网络中建立了一个映射
(5):由于第3步的洞开了,第4步的连接能进入了,所以B受到A的探测数据报之后发回给A一个ACK
5.一个系统模型:
上面的角色说明如下:SIP+STUN用户代理为本地客户端(UAC),SIP服务器用于获取映射地址,SIP服务器用于数据路由等
用工程中的抓包情况说明VOIP是在NAT顺利进行的。
首先用户注册:
这里SIP注册服务器为220.231.193.226。 SIP客户端为192.168.0.101。即处于内网中。则注册之后,SIP服务器获取到客户端的信息,方便客户端之间连接时SIP服务器通过查询SIP注册服务器之后进行目的端连接。可查看上图的via字段中地址和contact字段的地址
其次:STUN绑定映射地址:
客户端连接STUN服务器,地址为192.168.0.100,服务器返回响应信息,在XOR-MAPPED-ADDRESS属性中获取映射地址对(58.60.1.123:63166)。这个地址对用于后续的操作(如客户端进行呼叫请教时修改其SDP报文字段的C和M参数)
接着,SIP呼叫请求:
从上面一步分析指导,客户端发送INVITE请求时,会把原本私网地址和端口号修改为映射地址对,编程公网能路由的地址对。图中加深部分即为修改的情况。
6.TURN:
*RFC5766/TURN:
全称为:TraversalUsing Relays around NAT.还有一种称为:RelayExtensions to Session Traversal Utilities for NAT,即STUN的一种扩展。
*TURN和STUN的联系:
共同点:都是通过修改应用层中的私有地址达到NAT穿透的效果。
异同点:TURN通过通讯的“中间人”方式实现穿透,TURN用于对称NAT比较多,STUN用于非对称NAT
*TURN工作原理:
查看协议文档。这个比较好理解,就是获取对方的映射对之后,帮忙转发到目的地址中。
7.ICE:
*RFC5245/ICE
ICE全称“Interactive Connectivity Establishment”
利用了STUN及STUN的扩展TURN。ICE可以被任何请求/问答模式的协议使用。
*ICE原则:
尽可能实现直接链接,迫不得已情况才使用中继形式
8.ICE扩展:
*进行ICE扩展的原因:
在对称NAT类型之间的传输时,需要用到中继服务器。负载要求高,延时等影响
*如何实现扩展:
进行对称NAT类型的端口预测,实现直接连接
*端口预测:
这里描述的NAT类型为端口敏感性对称NAT,即映射IP不变,端口递增或递减情况。描述如下:
(1)A(B)向ICE服务器的UDP端口1发送STUN请求,得到映射地址的端口号P1.
(2)A(B)向ICE服务器的UDP端口3发送STUN请求,得到映射地址的端口号P2.得端口间隔为?P = P2-P1。根据?P得到实际建立连接时被分配的端口号位P^now=?P+ P2.
(3)A向预测到的地址进行验证,向B发送数据包,打了一个洞
(4)B执行和步骤3的操作,从而穿过洞直接进入A中