一.背景知识
NAT(Network Address Translators)的作用是将私网地址映射为公网地址,可以实现多个私网主机公用相同的公网IP地址,以解决IPv4地址不足的问题。一般的NAT在默认情况下只允许内网数据发往外网并接收已知的外网地址的访问,而阻止陌生的外网地址发送来的数据。所谓的已知是指该外网地址在session中有记录。
根据其工作方式,NAT可以分为两大类型:
1. 基本的NAT
将私网地址转换为公网IP地址,不改变TCP/UDP端口。鲜有这种类型的NAT。
2. NAPT(Network Address/Port Translators)
这是最普遍的情况。当数据报通过NAT时,修改IP地址和端口。NAPT在[私网IP:端口]
和[公网IP:端口号]之间建立绑定(Symmetric NAT中所谓的绑定只在同一个session中有效)。
NAPT又分为两类:
1) Cone NAT(圆锥形NAT)
这是最常见的类型。进一步可分为三种:
A. Full Cone NAT(完全圆锥NAT)
当内网主机发出一个对外的会话连接,就在NAT创建了一个公网/私网地址,此后,
NAT将任何外网主机发送给这个公网地址的数据转发给私网主机。这种类型的NAT很少。
B. Restrict Cone NAT(受限圆锥NAT)
当内网主机发出一个对外的会话连接,NAT会记录该外网的IP。此后,只允许这个
IP传送数据到私网主机。
C. Port Restrict Cone NAT(端口受限圆锥NAT)
与上种不同的是,NAT要记录外网IP和端口。此后,只允许这个[IP:端口]传送数
据到私网主机。
注:以上的会话有生存周期,一般指直到内网的端口解除绑定。私网/公网绑定只在会话生存周期内有效。
2) Symmetric NAT(对称型NAT)
对每一次会话,都分配不同的公网端口。当同一个[私网IP:端口]向两个外网主机发送
数据时,NAT会分配两个不同的端口。这是NAT打洞技术面临的最棘手的问题。因为通信对方无法知道打洞的端口号是多少。
NAT的存在使得两台私网内主机要直接通信变得异常困难,要实现两台私网主机直接通信,必须实现对NAT的穿透。现有的几种穿透NAT的方法有:通过服务器中转、MidCom、STUN、TRUN、NAT Hole Punching等。
二.STUN
STUN(Simple Traversal of UDP through NATs)是一种客户机-服务器网络协议,它允许位于NAT后的主机找出自己的公网地址,查出自己位于哪种NAT之后以及NAT为本地端口所绑定的公网端口。这些信息对于两台私网主机建立连接是有用的
如下图所示,STUN检测NAT的步骤是这样的:(设有私网内主机A,NAT B,A在B之后;另有公网服务器S,S必须拥有至少2个公网IP)
1)A向S的地址[IP1:PORT1]发送一个UDP包,S收到后通过[IP1:PORT1]给A返回一个UDP包,包中记录了S收到包的IP地址和端口号(这个IP地址一定是A的公网地址)。A必然能接收到这个返回包(因为连接是由A发起的),那么A对收到包中的IP和自己的IP进行对比,若相同则A与S之间不存在NAT(也就是说自己在公网);若不同则有NAT存在,继续下一步判断。
2)A请求S用它的另一个IP地址和端口号[IP2:PORT2]发送给A一个UDP包。若A能收到这个包,那么说明NAT B对外来包不进行过滤,即B是所谓的罕见的Full Cone NAT。若A未收到这个包,则继续下一步判断。
3)与第一步类似,A向S的另一个地址[IP2:PORT2]发送包,S收到后返回一个包,包中记录了A的公网IP地址和端口号。A必然能收到这个包(因为连接是由A发起的)。若包中的端口号与第一步中A收到的端口号不同,那么B一定是我们最不希望看到的Symmetric NAT(因为B为A的同一个端口发起的两次连接分配了两个PORT),若包中的端口号与第一步中的端口号相同,则继续下一步判断。
4)现在这剩下受限圆锥NAT和端口受限圆锥NAT两种可能了。A向S的地址[IP2:PORT2]发送请求,要求S用于与第三步不同的端口向A发送包。若A能收到这个包,则B是受限NAT,若收不到,则是端口受限NAT。