为什么会有NAT
犹如windows统治着绝大部份桌面系统一样,TCP/IP也是网络协议中的实际统治者,而IP正是这个协议统治的基础,作为标识TCP/IP网络中每个结点的IP地址,由于它只有32个bit的空间,随着网络的发展,它变得越来越稀有,再加上IP地址地区分配的极端不平衡,已使一些地区比如亚洲部分国家的IP资源很快就会用完,在IPv6还没有普及开来之时,为了解决IP地址的燃眉之急,我们需要一种手段来尽量减少对公网IP的使用,这种手段就是NAT(Network Address Translator):网络地址翻译器。
NAT的原理
NAT怎么能够节约公网IP地址呢?这是因为它能够让由私有IP构成的局域网内所有的计算机通过一台具有公网IP和NAT功能的计算机进入公网(Internet),比如上网冲浪,这样一个局域网就只需要一个或很少几个公网IP就行了,从而达到了节约公网IP地址的目的。也许你要问了,为什么需要NAT呢?局域网的私有IP计算机不是能够通过网关直接进入公网吗?非也,内网IP的数据包根本就不可能在公网上传播,因为公网上的路由器都是屏蔽掉了这些私网IP的,这是因为私有IP本来就是人为保留出来专供私有网络通信用的(RFC 1597中描述)。从另一个角度说,即使私有数据包能够到达公网目标地址,目标地址的响应包也不可能返回真正的源地址,因为源地址是私有IP,目标发送的响应包一种可能是被目标地址所在的拥有相同网络号的内网接收,一种可能就是这种子网不存在,数据包被抛弃。所以内网数据包在进入公网之前,必须被翻译成公网IP,这就是NAT的功能,而且NAT技术发展到现在,已不仅局限于翻译IP地址,现在实际翻译时,它不光翻译IP地址,还会翻译TCP/UDP端口。由于这个功能,NAT通常都位于网关计算机上,起着一种路由器的作用,为了讲述方便,以后我们就称这台网关计算机为NAT设备。下面就来看看NAT翻译的基本过程(假如局域网192.168.0.0的NAT设备公网IP是218.70.201.185,私有IP是192.168.0.1,现在客户机192.168.0.88要通过NAT设备访问cn.yahoo.com的网页,cn.yahoo.com的IP是202.43.216.55)。
当客户机192.168.0.88通过IE向http://cn.yahoo.com发出请求时,它发出的数据包含有下面的信息:
源地址和源端口:192.168.0.88:1234
目标地址和目标端口:202.43.216.55:80
当这个数据包到达NAT设备时,它会检测到这个数据包是要发向公网的,所以它会对源IP地址和端口进行修改(翻译),并在映射表中新建IP和端口的映射条目,然后再把修改的数据包转发出去,下面就是修改后数据包的相关信息。
源:218.70.201.185:8999
目标:202.43.216.55:80 (无需变)
当cn..yahoo.com响应时,它会把数据包发给NAT设备,它的数据包含有下面的信息,
源:202.43.216.55:80
目:218.70.201.185:8999
当NAT设备收到响应时,它会检查它的IP地址/端口映射表,并且会找到218.70.201.185:8999与192.168.0.88:1234的映射条目,于是它又修改数据包,然后把数据包转发给192.168.0.88。相关数据包信息如下:
源:202.43.216.55:80
目:192.168.0.88:1234
具体的翻译步骤就如图1所示,其中图1黑线左侧是内网发向公网的翻译过程,右侧则是公网发向内网的翻译过程,从中可以看出,翻译过程也是从上层向下层进行的。
从上面可以看出,最开始发起连接的内网计算机(这里是192.168.0.88)对网关进行NAT翻译是一无所知的,它根本就不知道网关对它的数据包“做了手脚”,上面所讲的可以说是最理想的翻译,这种翻译对IP地址和端口信息只存在于IP首部和TCP/UDP首部的数据包是非常适合的,但恰恰这个世界是复杂的,网络世界也不例外,每种技术都会有它的缺陷,下面就来看看NAT所面临的网络连接问题。
NAT的缺陷
在NAT出现之后,大家听到的多半都是对它的赞美之声,知道它可以为我们节省公网IP,可以保护我们的内部网络,对它的缺陷却知之甚少,甚至不知道我们遇到的很多网络问题就是由它造成的,比如我们在NAT设备后使用MSN Messenger进行语音聊天时却往往不能成功,其实这就是NAT惹的祸。NAT的缺陷主要表现在以下几方面。
(1) 不能处理嵌入式IP地址或端口
NAT设备不能翻译那些嵌入到应用数据部分的IP地址或端口信息,它只能翻译那种正常位于IP首部中的地址信息和位于TCP/UDP首部中的端口信息(如图2),由于对方会使用接收到的数据包中嵌入的地址和端口进行通信,这样就可能产生连接故障,如果通信双方都是使用的公网IP,这不会造成什么问题,但如果那个嵌入式地址和端口是内网的,显然连接就不可能成攻,原因就如开篇所说的一样。MSN Messenger的部分功能就使用了这种方式来传递IP和端口信息,这样就导致了NAT设备后的客户端网络应用程序出现连接故障。
要解决上面的嵌入式地址和端口问题,现在大多数都是通过特定的NAT编辑器来实现的(图1步骤所示),比如windows 2000就提供了针对FTP、PPTP、ICMP和TCP上NETBIOS各自的NAT编辑器,按照这种方法,每个应用协议都需要一个独立的NAT编辑器,但应用协议如此众多,显然这种方法不可能满足所有需求,所以我们仍需要更完美的解决方案,下面将会讲到。
(2) 不能从公网访问内部网络服务
由于内网是私有IP,所以不能直接从公网访问内部网络服务,比如WEB服务,对于这个问题,我们可以采用建立静态映射的方法来解决。比如有一条静态映射,是把218.70.201.185:80与192.168.0.88:80映射起的,当公网用户要访问内部WEB服务器时,它就首先连接到218.70.201.185:80,然后NAT设备把请求传给192.168.0.88:80,192.168.0.88把响应返回NAT设备,再由NAT设备传给公网访问用户。
(3)有一些应用程序虽然是用A端口发送数据的,但却要用B端口进行接收,不过NAT设备翻译时却不知道这一点,它仍然建立一条针对A端口的映射,结果对方响应的数据要传给B端口时,NAT设备却找不到相关映射条目而会丢弃数据包。
(4)如果NAT本身又位于另一个NAT之后,则也会出现一些问题,为了节约IP资源,现在很多的ISP在它们内部架设NAT,然后再把服务提供给用户,比如长城、聚友等ISP通常都是以城域网的方式为用户提供宽带上网服务的。
(5)一些P2P应用在NAT后无法进行
对于那些没有中间服务器的纯P2P应用来说,如果大家都位于NAT设备之后,双方是无法建立连接的。因为没有中间服务器的中转,NAT设备后的P2P程序在NAT设备上是不会有映射条目的,也就是说对方是不能向你发起一个连接的。
解决上述问题的权宜之计
要解决上面的部份问题,可以应用NAT穿越技术(NAT Traversal),NAT穿越技术拥有这样的功能,它能够让网络应用程序(如MSN Messenger)主动发现自己位于NAT设备之后,并且会主动获得NAT设备的公网IP,并为自己建立端口映射条目,注意这些都是NAT设备后的应用程序自动完成的,也就是说,在NAT穿越技术中,NAT设备后的应用程序处于主动地位,它已经明确地知道NAT设备要修改它外发的数据包,于是它主动配合NAT设备的操作,主动地建立好映射,这样就不像以前由NAT设备来建立映射了。这样就会解决很多以前由NAT引起的网络连接问题。
(1) 解决了嵌入式IP地址或端口的问题,因为现在应用程序已经知道了自己映射的公网条目,那么它在IP数据包的应用数据部分嵌入IP地址和端口时就会嵌入映射后的公网条目,这样对方通信时就不会出现问题了。
(2) 对于从公网访问内部网络服务,再也用不着手动去配置静态映射了,因为这一切已经由应用程序自动配置好了。
(3) 对于上面NAT缺陷部分所讲的第三种情况,由于是应用程序自己建立映射条目,那么它也会自动建立针对B端口的映射,而再也不会建立针对A端口的映射了。
(4) 对于那种没有中间服务器支持的P2P应用来说,它们之前通信也不会再有问题了,因为映射条目已经建立好了。
不过对于那种NAT设备位于另一个NAT设备之后的情况,NAT穿越技术也无能为力,所以你选择ISP的时候需要关注这一点。
应用NAT穿越技术
那怎么应用这种技术呢?其实NAT穿越技术依赖于UPnP协议的支持,也就是说NAT设备必须支持UPnP,支持NAT穿越技术;而网络应用程序一样也需要支持UPnP,支持NAT穿越技术,只不过,这通常都是通过调用相关的NAT Traversal API实现的,window XP默认已经安装了NAT Traversal API,当然网络应用程序要调用它仍然需要进行一些修改,现在的MSN Messenger就支持调用NAT Traversal API了,我们也可以在win98和Win Me中安装NAT Traversal API,需要使用windowsXP的网络安装向导进行安装,并且IE应该是6.0版本。Windows 2000现在还不支持NAT Traversal API。对于NAT设备来说,它也必须加入对NAT Traversal的支持,需要在NAT设备中应用UPnP技术。其实windows XP的Internet连接共享(ICS)就已经是这样一个NAT设备了,它支持 UPnP IGD 标准 0.9 版,也就是如果通信双方的NAT设备都是使用windows XP的ICS,而客户端也都是winows XP操作系统的话,那么你们使用MSN messenger进行音频通信等应用就不会再有问题了,为了更直观地看到这种应用的结果,我抓了一张在window XP 的ICS上客户端MSN Messenger自己主动建立的端口映射图片,如图3:
这是我在一台客户机上与一个公网用户进行白板交流后MSN在ICS中建立的映射条目,图中打勾者就是MSN Messenger自动建立的端口映射。除了Windows XP中的ICS,市场上也有一些支持NAT穿越技术的硬件设备,它们有一个专用名称叫IGD(也就是Internet网关设备),比如D-Link DI-804。
解决NAT问题根本之道
虽然NAT Traversal技术可以解决很多NAT引起的连接问题,但它仍不是万能的,比如它就不能解决位于多重NAT后的问题。何况NAT Traversal的应用还需要修改应用程序和在NAT设备中增加对它的支持,这些都应该是延缓NAT Traversal技术普及的障碍。NAT是因公网IP地址紧缺而生的,所以要根本解决NAT的问题,就是用不会产生地址稀缺问题的IPv6协议替代现在的IPv4,让NAT消亡,这样就解决了NAT的问题,当然在特定的环境下,即使IPv6替代了IPv4,NAT及NAT Traversal仍将会存在下去。