NAT穿透原理与实现
NAT英文全称为“Network Address Translation”,就是网络地址转换或网络地址的翻译。现在太多人使用互联网,所以导致IP地址短缺与路由表不断增大,这样使得有很多的用户接入互联网都出现困难。简单来说,NAT就是自动地把内网每个主机的IP映射到公网IP的随机端口上,当然每台主机的不同端口也会自动映射到公网IP的不同端口,如果想要知道哪个端口,只能用扫描或通过公网主机辅助。
使用NAT技术可以解决这一难题,它的原理是能够使一个机构内的所有用户通过有限的数个(或1个)合法公网IP地址访问互联网,从而节省了互联网上的合法公网IP地址。另一方面,通过这个地址转换技术,可以隐藏内网里面的主机的真实IP地址,从而提高网络的安全性。
但是使用了NAT技术会带来很多的不便,就像如果在本地建了一个站点,想让公网通过IP访问内网的这个站点,那就必须在上级路由里面把本地建了站点的主机映射到DMZ(DMZ中文为隔离区,主要用于将内网主机的指定端口映射到公网IP的指定端口)。就像下图那样,如果本地主机是PC-A2,你要让公网访问到你的80端口,只能通过DMZ把本地主机的80端口映射到公网IP的80端口。
但是在我大天朝这样是不行的,因为网络运营商他不止NAT了一次,当然也有独立IP的宽带。在上图每个主机可以理解为每个用户,就是说一个公网IP会有N个人共用。而每个防火墙就可以理解为每个绑定的公网IP,跨防火墙可能会跨运营商以及绝对会跨公网的IP。
下面的才是真实的拓扑图,因为每个用户都可能自己接一个路由器去共享上网(若是独立IP的宽带,那么就真的是上面的图那样)。
从上图看出,已经经过了2次NAT,其实不止2次的,有些地区的黑心运营商可能在用户上级就已经NAT了多次,分发了几百个内网IP。那么如何才能把PC-A1的数据包穿透多次NAT到达PC-B1呢?下面是大概的结构图。
PC-A1和PC-B1拿到的是NAT多次的内网IP,要穿透就必须打洞,因为如果PC-A1建立了一个端口25431,那么防火墙A用了NAT,PC-A1的25431端口会随机的映射到公网IP的端口上(但端口不会是25431,也有很小的机率会是),就是说通过PC-A1的公网IP加上NAT后的端口就可以访问PC-A1的指定端口。PC-B1想拿到PC-A1的25431端口并进行连接,就必须要有防火墙A的NAT映射后的端口。下图是穿透程序的简单原理图。
Server:服务端会一直监听指定的端口,当收到端口的数据包就验证是不是客户端发送的,验证通过就返回给客户端。
Client:客户端拿到了服务端的公网IP,然后通过端口扫描,一个个端口地尝试连接服务端,如果成功连接就发送一个验证的数据包到服务端,服务端收到了数据包就验证是不是客户端发来的,如果是就返回一个数据包给客户端。
只要客户端连进了服务端,那么服务端PC-A1就可以拿到客户端PC-B1的NAT端口号,反之PC-B1也能拿到PC-A1的NAT端口号,这样就成功的打洞穿透了NAT。
上面说到的本地站点穿透NAT是不可能的,因为站点一般都是用80端口,NAT技术会随机分发端口给内网主机,你拿到80端口的概率是很小的,因为最大端口数是65535。
至于程序的话,我已经写了一个半成品了,单向NAT穿透是可以的,但是双向NAT穿透还没有写完,以后我会放出程序的代码。