NAT类型和打洞流程

一、NAT

1. 含义

      NAT技术(Network Address Translation,网络地址转换)是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术,它使得一定范围内的多台主机只利用一个公共IP地址连接到外网,可以在很大程度上缓解了公网IP地址紧缺的问题。

2. 实现方式

    静态转换、动态转换、端口多路复用。

    静态转换:是指将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一成不变的。通过静态配置,把一个固定的私网IP地址和端口关联到一个公网地址和端口,这种方式适用于在NAT网关上把一个知名服务(如HTTP)映射到一个内部主机上。

    动态转换:是指将内部网络的私有IP地址转换为公用IP地址时,IP地址对是不确定的,而是随机的,所有被授权访问Internet的私有IP地址可随机转换为任何指定的合法IP地址。也就是说,只要指定哪些内部地址可以进行转换,以及用哪些合法地址作为外部地址时,就可以进行动态转换。

    端口多路复用:是指改变外出数据包的源端口并进行端口转换,即端口地址转换(Port Address Translation,PAT)。采用端口多路复用方式,内部网络的所有主机均可共享一个合法外部IP地址实现对Internet的访问,从而最大限度地节约IP地址资源。同时,又可隐藏网络内部的所有主机,避免来自Internet的攻击。因此,目前网络中应用最多的就是端口多路复用方式。

3. 分类

NAPT又分为锥型(Cone)和对称型(Symmetric),它们的区别在于,在NAT已分配端口号给Client A的情况下,如果Client A继续用1235端口与另一外网服务器通讯,锥型NAT还会继续用原来62000端口,即所分配的端口号不变。而对于对等型NAT,NAT将会分配另一端口号(如62001)给Client A的1235端口。也就是说,同一内网主机同一端口号,对于锥型NAT,无论与哪一外网主机通讯,都不改变所分配的端口号;而对于对等型NAT,同一内网主机同一端口号,每一次与不同的外网主机通讯,就重新分配另一个端口号。

目前比较常用的NAT类型是完全锥型NAT。

   通过内部同一个socket 对外不同的ip和端口发送数据,如果nat提供一个统一的publish ip 和端口,那么外面多个人进来汇聚到一个端口,像锥形,称为锥形。反正就是对称性。

     Full Cone NAT全锥形NAT、Restricted Cone NAT限制锥形NAT、Port Restricted Cone NAT端口限制锥形NAT、Symmetric NAT对称型NAT。

      Full Cone NAT全锥形NAT:内网主机建立一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,任何外部主机只要知道这个(PublicIP:PublicPort)就可以发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。

      Restricted Cone NAT限制锥形NAT:内网主机建立一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机IP发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。

      Port Restricted Cone NAT端口限制锥形NAT:内网主机建立一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机(IP,Port)发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,Port)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。

      Symmetric NAT对称型NAT:内网主机建立一个socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,NAT会为其分配一个(PublicIP-2,Port-2), 以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2).如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,则Port-1和Port-2肯定不同,也就是说一定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。此外,如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,否则即使他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机。

1. 类型检测

      前提条件:一个提供两个公网地址(通信地址分别设为:Endpoint1与Endpoint2)的服务器S进行UDP端口数据监听并根据客户的要求给出响应;待检测的用户可以正常进行UDP通信。

步骤1.检测主机是否位于NAT后

      为了检测IP地址是不是公网地址,主机A首先发送任意一个UDP数据包给服务器S(Endpoint1),S收到包之后,用Endpoint1将接收到数据包头的IP地址和端口打成一个UDP反馈包发送给用户A。A在收到反馈包之后,比较自身的Endpoint和反馈包中的Endpoint,如果一样则说明A不位于任何NAT之后,否则,就是位于NAT之后,这里并不能判断NAT的具体属于哪一种类型。

步骤2.检测NAT是否是全锥型

      为了检测所处的NAT是否是全锥型的,主机A向服务器S(Endpoint1)发送UDP数据包后,服务器用Endpoint2将接收到数据包头的IP地址和端口打成一个UDP反馈包发送给用户A。另外,A在发送UDP数据包后,立即开始端口侦听,设定一个等待时间上限,防止无限堵塞(因为接收是一个While循环)。这样进行若干次,如果A每次都没有收到数据包,说明A所处的NAT类型不是全锥型的;相反,在这整个过程中只要收到一次服务的包,就说明A所处的NAT类型是全锥型的。

步骤3. 检测NAT是否是对称型

      为了检测所处的NAT是否是对称型的,主机A向服务器S(Endpoint1)发送UDP数据包,服务器S(Endpoint1)在收到数据包后,用Endpoint1将接收到数据包头的IP地址和端口打成一个UDP反馈包发送给用户A。另外,A在发送数据包后,开始侦听端口并接收数据,设定一个等待时间上限,防止无限堵塞(因为接收是一个While循环)。与此同时,主机A用同一个套接字向服务器S (Endpoint2)发送UDP数据,Endpoint2发送与上面类似的UDP回馈包。在A的整个数据接收过程中,如果收到的服务器反馈数据包中标识自身的IP地址和端口存在不相同的情况,就说明NAT是对称型的,否则就不是。

步骤4. 检测NAT是限制锥型的还是端口限制锥型

     最后,为了检测所处的NAT是限制锥型的还是端口限制锥型的,主机A向服务S的Endpoint1发送UDP数据包,服务器用与Endpoint1相同的IP地址和不同的端号将带有A的Public Endpoint的UDP反馈包发送给A。另外,A在发送数据包后,立即侦听端口和并进行数据接收,设定一个等待时间上限,防止无限堵塞(因为接收是一个While循环)。重复若干次。如过在整个过程中,用户A收到S发来的数据包,就说明NAT是限制型的;否则就说明NAT是端口限制型的。

 

二、打洞

      NAT技术虽然在一定程度上解决了IPv4地址短缺的问题,在构建防火墙、保证网络安全方面都发挥了一定的作用,却破坏了端到端的网络通信。NAT阻碍主机进行P2P通信的主要原因是NAT不允许外网主机主动访问内网主机,因为NAT设备上没有相关转发表项,要在NAT网络环境中进行有效的P2P通信,就必须寻找相应的解决方案——NAT穿越打洞。

      下面分各种NAT场景(如图2)来说明UDP打洞的过程。

 

 

     假设现在有A和B通信双方,同时为了便于描述打洞过程,假定图2中的NAT类型均为Full Cone NAT:

   (a)A和B都处于公网下,无需打洞,A和B可直接P2P直连。

   (b)A处于公网,B在内网。若A去连B,由于B没有向A发送过数据,A的数据包会被B的NAT1丢弃,所以即使A知道了B通过NAT1转换后的地址和端口,也是无法连接成功的。但是由于A在公网下,所以反过来B可以连接A,P2P通信成功。
   (c)A和B都处于内网,分属不同的内网,它们彼此的内网地址在外网中是没有路由的,所以发往各自内网地址的UDP数据包会发送到错误的主机或者根本不存在的主机上。由于双方都不知道对方的公网IP和端口,就会无从下手,所以要在A和B之间架设一台服务器S来为它们牵线,而且S是处在公网,以保证A和B都能连接到S。A和B登录时都首先连接S,S就会知道A和B经过NAT后的IP和端口,当A想要连接B时,就向S发出请求,S会把B经过NAT后的IP和端口告诉A,同时S向B发送A经过NAT后的IP和端口,并要求B发送数据给A,B发送数据到达A时会被A的NAT抛弃,但是B的NAT会有B发送数据到A的记录,这时A再向B发送数据时就会被B的NAT放行,因为B曾经向A的外网IP和端口发送过数据。A向B的外网地址发送消息的过程就是“打洞”的过程,一旦A与B都向对方的外网地址发送了数据包,就打开了A与B之间的“洞”,一旦应用程序确认已经可以通过往对方的外网地址发送数据包的方式让数据包到达NAT后面的目的应用程序,程序会自动停止继续发送用于“打洞”的数据包,转而开始真正的P2P数据传输。这个过程可借助于网上的一个形象比喻来理解(见图3)。

 

   (d)NAT1和NAT2是由ISP(Internet Service Provider)提供的NAT设备,提供将多个用户节点映射到有限的几个公网IP的服务。NAT3作为NAT1的内网节点将把用户的家庭网络或内部网络接入NAT1的内网,然后用户的内部网络就可以经由NAT1访问公网了(NAT4同理)。从这种拓扑结构上来看,只有服务器S与NAT1、NAT2是真正拥有公网可路由IP地址的设备,而NAT3和NAT 4所使用的公网IP地址,实际上是由ISP服务提供商设定的(相对于NAT1和NAT2而言)内网地址(这个由ISP提供的内网地址相对于NAT1和NAT2被称之为“伪”公网地址)。现在假定A和B希望通过UDP“打洞”完成P2P直连。最优化的路由策略是A向B的“伪公网”IP上发送数据包。由于从服务器S的角度只能观察到真正的公网地址,也就是NAT3、NAT4分别通过NAT1、NAT2转换的外网地址,非常不幸的是A与B是无法通过服务器S知道这些“伪”公网的地址,而且即使客户端A和B通过某种手段可以得到NAT3和NAT4的“伪”公网地址,我们仍然不建议采用上述的“最优化”的打洞方式,这是因为这些地址是由ISP服务提供商提供的,或许会存在与客户端本身所在的内网地址重复的可能性,这样就会导致打洞数据包无法发出的问题。因此客户端别无选择,只能使用由服务器S观察到的A,B的公网地址进行“打洞”操作,打洞过程与(c)类似。

   (e)A和B位于同一个NAT设备后面,并且处于同一局域网中,发出的数据包不需要路由,可进行速度较快的常规P2P通信。另外,A和B发往对方公网地址的UDP数据包不一定会被对方收到,这取决于当前的NAT设备是否支持不同端口之间的UDP数据包传输(即Hairpin转换),就算支持,应用程序也应该优先选择上述常规的P2P直连,否则势必会造成数据包无谓地经过NAT设备,这是一种对资源的浪费。

  (f)由于A和B不在一个内网中,所以相对于(e)而言,就不能不经过NAT让A和B直接相连,这样情况下就需要NAT1支持Hairpin转换,虽然目前也有很多NAT设备不支持类似这样的“Hairpin转换”,但是已经有越来越多的NAT设备商开始加入对该转换的支持中来。同理(g)(h)。

二、webrtc打洞框架

 

      Peer与STUN服务器交互采用的是STUN协议,STUN服务器返回Peer的公网地址,地址形式为[IP:port]。

      L和R都获取到了自己的局域网地址和公网地址后通过信令服务发送给对方,然后彼此都有了对方的地址。

      RFC5245定义这些地址为candidate,按照局域网 > 外网 > TURN地址的优先级顺序为candidates排序后进行打洞测试。

      打洞过程就是双方不停地往彼此的端口发包,既能收到对方发的包,也能收到自己发出去的回包,就说明打洞成功。失败的话,就通过TURN服务器进行转发。

注:以上部分描述和图挑选自网上资料与论文。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值