曾经看到C司内部一个官方统计,全球有近一半的网络通信故障是由于NAT造成的。与之对应的是,排在C司软件BUG之首的也是和NAT技术相关,从那一刻起,就开始特别关注NAT技术及相关领域。
90年代中叶,一位同学从图书馆借来一本计算机书籍《TCP/IP协议》,乳白色的封面,当时身边大多是工科的研究生,可没有几个人看得懂,即使知道一点,也仅限于靠死记硬背的OSI模型分层,以及每层所实现的功能。厉害一点的同学还知道,分层是为了提高代码的重用,这些初级的概念在同学们中间已经可以吹嘘半天…
经过20多年的互联网爆发式发展,TCP/IP协议虽然谈不上家喻户晓,但每一位的生活却离不开它,现代社会高效率的生活节奏是和TCP/IP协议息息相关的。这是TCP/IP协议设计之初没有想到的景象,要知道TCP/IP协议最初是用来在美国军方内部通信使用的,但架不住市场的召唤,打败天下无敌手,称霸互联网网络层、传输层协议。
互联网上电脑们能够通信,并且能区分彼此的身份,是依赖于每台电脑拥有一个全球唯一的IP地址,但随着电脑越来越多,IP地址空间开始捉襟见肘了,IPv4地址空间只有32个二进制位,理论上有42.95亿个IP地址,但去除一些特殊保留地址,能够用于电脑通信使用的IP地址只有不到30亿。
越是资源稀少的物品,越能够引起人类的哄抢,最终的结果是IP地址被哄抢一空。那没有IP地址如何上网?用户上不了网,如何发展IT产业?
有人说,把IPv4地址扩展得更长一点不就可以了吗?
这是IPv6协议思维,IPv6地址空间128位长,IP地址的数量多到什么程度呢?地球上每一粒沙子都分配一个IP地址尚且有余,人一旦穷怕了,富裕起来会非常贪婪。
问题是IPv6网络和IPv4网络不能直接通信,需要使用网关做地址转换(NAT64),IPv6种种的不便利严重影响它的流行与普及,IPv6已经喊了那么多年,到现在依然只是一个配角。
有人说,可否将IPv4扩展成48位,其它部分维持不变,依然还使用IPv4协议?
这意味着全球的电脑、路由器、交换机、防火墙等等硬件设备都需要升级软件,而在软件中嵌入了32位的IP地址的软件,也需要软件升级,这是一个多么浩瀚的工程,浩瀚到有人敢想,但没人敢做的程度。
在没有更好解决方案之前,业界开始了寻求过渡解决方案,于是网络地址转换(NAT)映入了眼帘。
NAT
在NAT技术标准的RFC里有这么几句话:NAT作为TCP/IP技术补丁,是作为一个过渡性的技术方案,在过渡期间,使得全球亿万万用户上网成为可能。同时,期望有创新的、革命性的技术解决方案诞生,以完全代替NAT技术。
由于很多协议在NAT技术之前已经存在,NAT作为技术补丁,需要一个个协议去打补丁,这是非常繁重的工作。
值得庆幸的是,网络流量绝大多数是以TCP/UDP传输的,作为一种技术补丁,先要解决主要矛盾,即如何解决TCP/UDP上网流量。Okay,接下来看看NAT技术的解决思路。
NAT解决方案
NAT设备位于局域网与互联网的边界,在NAT眼里,局域网是内部(Inside)区域,互联网是外部(Outside)世界。在局域网内,用户可以使用私有IP地址互相通信,这属于内部通信,NAT设备对内部通信不参与,因为NAT的存在是为了解决Inside和outside之间的通信。
假设inside区域的小明开了一个浏览器窗口,使用10.0.0.1:1025访问互联网(outside)区域服务器1.1.1.1:443,问题来了,小明能否同时再开一个窗口访问1.1.1.1:443,使用相同的10.0.0.1:1025?
绝不可能,如果这样的话,两次访问的流量服务器IP地址(10.0.0.1)、端口号(1025)是完全一样的,这样服务器会混淆两次通信会话,从而引起通信的紊乱,所以绝对不允许这样的端口冲突发生。
同学们不禁要问,小明的电脑是如何保证每个通信程序使用不冲突的端口号?
由操作系统集中管理,端口号一共16位,取值范围为0-65535,操作系统为了避免冲突,将这65536个端口资源统一调度,其中0-1024是知名端口,保留给相应的服务使用,1025-65535端口号可以留作普通进程使用,当一个程序执行时,如果该程序没有明确指定端口号,操作系统会从空闲的端口资源中选取一个,供该程序使用。如果该程序明确指定了端口号,操作系统如果检查发现该端口号空闲并允许该程序使用,该程序可以继续用该端口继续运行。
无论是以上哪种方式,都可以避免端口冲突的状况的发生。
大家学习TCP/IP协议,一定听过五元组的概念,五元组的概念来源于TCP连接,
(TCP,源IP,源端口,目的IP,目的端口)
这个五元组定义了一个session,每个session的五元组至少要有一项区别于别的session的地方。有同学说,每个TCP连接的的五元组的“TCP”都是一样的,那么为了保证每个session区别于别人的地方,只能依靠其它四元组了。
但是,往往目的IP、目的端口也是固定不变的,此话怎讲?
比如同学们访问知乎的APP,这是一个https连接,假定知乎的服务器IP为6.6.6.6,在443端口侦听同学们的连接请求。
现在再来审视这个五元组:
(TCP,源IP,源端口,6.6.6.6,443)
那么意味着,只能依靠(源IP,源端口)来区分彼此了。
又有同学说,如果是同一台主机,假设主机的IP =1.1.1.1,那么五元组就有四个元素是固定不变的了,如下图:
(TCP, 1.1.1.1,源端口,6.6.6.6,443)
那么对于同一台主机,访问同一台服务器的同一个服务(端口),只能依赖于不同的源端口。
操作系统统一管理端口号资源,保证每一个进程的端口号是唯一的,这样即使访问同一台服务器的同一个服务(端口),五元组也是不同的,这样就不会造成通信的紊乱。
领取专属 10元无门槛券
私享最新 技术干货