代码改变世界

WebRTC笔记(四)NAT、STUN和ICE

2020-07-12 21:44  jiayayao  阅读(1232)  评论(0编辑  收藏  举报

   一、NAT

    NAT(Network Address Translator),网络地址转换。NAT是在IPv4地址日益缺乏的情况下产生一种缓解地址问题的方案。它的主要目的是为了地址重用。 NAT的基本思想是,由NAT设备(比如家用路由器)修改从私有网络发送到互联网的IP报文的源地址字段,以及修改从互联网发送到私有网络的IP报文的目标字段。分为两类,一类是基本NAT,一类是NAPT(Network Address/Port Translator)。

    基本NAT就是将这个节点的子网内IP转化为一个全球唯一的IP,然后发送出去。(基本NAT会改变原IP包中的ip地址,但不会改变端口)。NAPT也会改变端口。目前基本全是NAPT。

    举例,如果某台内网的设备A经过网关(NAT设备)想要访问外网Server,首先NAT有一个全球唯一IP地址,会将设备A发送给NAT的数据报中的IP地址修改为这个全球唯一IP地址,接着NAT设备会为这个设备创建一个session(一个抽象概念),并且为这个session创建一个端口,比如10000,然后改变这个数据包的源端口为10000.与此同时,NAT会记住端口与设备A的对应关系,从Server接收到的消息也会转发到设备A上。

二、NAT类型

    假设设备A需要访问Server2,此时如果NAT再次创建session和端口号,则称为Symmetric NAT;如果NAT创建session复用端口号的话,称为Cone NAT。目前Symmetric NAT较少见,绝大多数是Cone NAT。

   而Cone NAT又分为3种:

1. Full Cone全圆锥:NAT把所有来自相同IP地址和端口的请求映射到相同的外部IP地址和端口。任何一个外部主机均可通过该映射发送IP包到该内部主机;

2. Restricted Cone地址限制性圆锥:NAT 把所有来自相同内部 IP 地址和端口的请求映射到相同的外部 IP 地址和端口。但是只有当内部主机给IP地址为X的外部主机发送IP包,该外部主机才能向该内部主机发送IP包(多了一个顺序);

3. Port Restricted Cone端口限制性圆锥:与限制性圆锥类似,只是多了端口号的限制。即只有内部主机先向IP地址为X,端口号为P的外部主机发送1个IP包,该外部主机才能够把源端口号为P的IP包发送给该内部主机(在2的基础上多了端口限制)。

    可以看到内部向外部访问比较容易,但外部想访问内部较困难。怎么做呢?首先,必须在内网的NAT上打一个“洞”。这个洞不能由外部来打,只能由内网主机来打,而且这个洞是有方向的(时刻记住,打洞是为了让对方的数据过来)。比如从内部某台主机IP A向外部某个IP B发送一个UDP包,那么就在这个内网NAT设备上打了一个方向为外网IP B的洞。以后外网IP B就可以通过这个洞与内网IP A联系了。

    举例,如果Client A想向Client B发送信息,那么Client A发送命令给Server S,请求Server S命令Client B向Client A方向打洞。然后Client A就可以通过Client B的外网地址与Client B通信了。注意,仅仅是Client A和Client B互相知道对方的IP地址和端口,那么双方是否可以跳过Server S直接通信了呢?答案是不行的。因为出于安全原因,NAT对于这种不请自来的信息一般是会执行丢弃动作。

三、STUN

    STUN(Session Traversal Utilities for NAT, NAT会话穿透工具)是一种网络协议,目的就是进行NAT穿透。它使用RFC5389自动探测当前的NAT类型、IP和端口(RFC5389是在RFC3489的基础上改进而来,解决了3489 UDP穿透失败的一些问题)。

1. STUN协议

    包含20个字节的STUN header和0或者多个的Attribute的STUN body;

a. STUN header

    STUN Message Type:2个字节(16bit)类型;前2位必须是00;2位用于分类(c0和c1),包含4种类型(请求、指示、成功应答、错误应答),剩下的12位用于定义请求和指示。

  • 0b00:请求
  • 0b01:指示
  • 0b10:请求成功的响应
  • 0b11:请求失败的响应

0x0001 绑定消息

0x0101 绑定响应

0x0111 绑定错误

    STUN Message Length:2个字节(16bit)消息长度,注意,这里的长度不包括消息头;

    Magic Cookie:魔法数,4个字节,固定值0x2112A442,可以通过此魔法数识别一些属性

    Transaction ID:12个字节(96bit)事务ID,请求与服务器返回的响应事务ID相同;

b. STUN body

    每个消息头后有0或者多个属性,属性有12种

    每个属性进行TLV编码:Type(2字节),Length(2字节),Value。

2. STUN探测步骤

    设备A,NAT B,Server C有两个IP:IPC1,IPC2.

a.  A向IPC1发送一个UDP包,C收到后返回给A一个UDP包。当A收到此UDP包后,把此UDP中的IP和自己的IP做比较,如果是一样的,说明自己在公网;如果不一样,说明有NAT存在,执行2;

b. A向IPC1发送一个UDP包,请求IPC2向A返回一个UDP包,如果A收到了这个UDP包,说明NAT来者不拒,即full cone NAT.如果不是,则执行3;

c. A向IPC2发送一个UDP数据包,IPC2返回一个UDP包。分析UDP包中的port,如果和1返回UDP包中的port一样,则为cone NAT,否则为 symmetric NAT;

d. A向IPC2的一个端口port1发送数据包,要求IPC2使用不同于port1的端口port2发送数据包给A,如果A收到了,则为restricted NAT;如果A没收到,则为port restricted NAT.

    只要任意一台主机处于对称型NAT或对称型UDP防火墙后面就无法建立P2P连接,需要使用服务器进行中转,这就是TURN。(也就是说STUN不需要中转的穿透协议,TURN是需要中转的穿透协议?)

四、TURN

    TURN(Traversal Using Relay NAT),是一种资料传输协议, 允许在TCP或UDP的连线上跨越NAT或防火墙,保障双方能够百分之百进行通信。TURN是STUN的扩展,允许一个peer只使用一个relay address就可以和多个peer实现通信。TURN为每个peer分配一个中继地址,其他peer向A的中继地址发数据,TURN Server就会把数据准发给A(也就是说,数据经过了TURN Server的中转)。

五、ICE

    ICE(Interactive Connectivity Establishment),一种综合性的NAT穿透技术,是一种framework,可以整合各种NAT穿透技术,如STUN、TURN等。该framework可以让sip客户端利用各种NAT穿透方式打穿远程的防火墙。ICE方式能够在不增加整个系统复杂性和脆弱性的情况下,实现对各种形式的NAT进行穿透,使得媒体流在通信双方顺利传输。