简介
随着越来越多的家庭和小型企业添置计算机,它们会发现网络是一种非常强大的计算机资源共享工具。Internet 连接则是网络上更珍贵的资源,有可能被共享。为共享 Internet 连接,同时利用价格便宜、管理简单的家庭或小型办公网络,需要部署 Internet 网关。Internet 网关通常将 NAT (网络地址转换) 作为将多个主机连接到 Internet 以共享单个公共 IP 地址的途径。但不幸的是,该解决方案却会破坏多种网络应用程序。我们将在本文中对此加以说明。
现有的“NAT 穿越”技术允许网络应用程序检测是否存在本地 NAT 设备。检测到后,应用程序随即对 NAT 进行配置,定义相应的映射来解决兼容性问题。
本文属于概述性文章,将向网络应用程序的用户和开发人员简要介绍一下 NAT,介绍如何识别常见 NAT 问题,同时介绍应用程序如何使用 “NAT 穿越”解决这些问题。需要关注的 Internet 网关设备的一个重要特征是 UPnP 认证。使用者购买或从服务提供商那里租借 Internet 网关设备时,强烈建议只考虑那些通过用于 NAT 穿越的 UPnP 认证的设备,这是因为该功能对于满足用户、降低支持费用及使用更有创新性的服务和应用程序而言至关重要。
对网关设备厂商而言,在 Internet 网关设备中加入对 NAT 穿越的 UPnP 技术支持并不复杂,费用不高,也不用花大量的时间。通过使用 UPnP (已经是基于 Internet 标准和协议的),Internet 网关设备制造商就可以解决 NAT 穿越问题,并将优点延伸至大多数经过该设备的应用程序。这同许多应用程序开发人员或网关设备制造商不得不为解决上述问题而提供一次性解决方案形成鲜明的对比。本文并非旨在为希望在 Internet 网关设备中实施“NAT 穿越”的硬件制造商提供详细的指南。有关此信息,请参阅 UPnP 论坛 Web 站点。
Windows 体系结构、网络以及 UPnP 体系结构方面的知识会对充分理解本文会有所帮助,但并不是必需的。
什么是 NAT?
网络地址转换 (NAT) 是一个 Internet 工程任务组 (Internet Engineering Task Force,IETF) 标准,用于允许专用网络上的多台 PC (使用专用地址段,例如 10.0.x.x、192.168.x.x、172.x.x.x) 共享单个、全局路由的 IPv4 地址。IPv4 地址日益不足是经常部署 NAT 的一个主要原因。Windows XP 和 Windows Me 中的“Internet 连接共享”及许多 Internet 网关设备都使用 NAT,尤其是在通过 DSL 或电缆调制解调器连接宽带网的情况下。
NAT 对于解决 IPv4 地址耗费问题 (在 IPv6 部署中却没必要) 尽管很有效,但毕竟属于临时性的解决方案。这种 IPv4 地址占用问题在亚洲及世界其他一些地方已比较严重,且日渐成为北美地区需要关注的问题。这就是人们为什么长久以来一直关注使用 IPv6 来克服这个问题的原因所在。
除了减少所需的 IPv4 地址外,由于专用网络之外的所有主机都通过一个共享的 IP 地址来监控通信,因此 NAT 还为专用网络提供了一个隐匿层。NAT 与防火墙或代理服务器不同,但它确实有利于安全。
图 1:使用 NAT 设备进行 Internet 通信的网络示例。
正如固定电缆调制解调器或 DSL 调制解调器可以作为 NAT 设备一样,
PC 也可以作为 NAT 设备。
常规 NAT 操作
NAT 设备后面的客户端通常通过 DHCP (动态主机配置协议) 分配到专用的 IP 地址,或者由管理员进行静态配置。在该专用网络的外面进行通信时,通常会发生下列事情。
在客户机上
当应用程序想同服务器通信时,它将打开与源 IP 地址、源端口、目标 IP 地址、目标端口及网络协议相关联的套接字。这样可以识别通信所需的两个端点。当应用程序利用该套接字传输信息时,客户机的专用 IP 地址 (源 IP 地址) 和端口 (源端口) 将被插入数据包的源字段中。数据包的目标字段将包含服务器的 IP 地址 (远程主机 - 目标 IP 地址) 和端口。由于该数据包的目的地是该专用网络之外的某个位置,因此客户机将把该数据包转发给默认的网关。这种情况下的默认网关就是 NAT 设备。
NAT 设备上的输出数据包
NAT 设备将截获该输出数据包,然后利用目标 IP 地址 (服务器)、目标端口、NAT 设备的外部 IP 地址、外部端口、网络协议及客户机的内部 IP 地址和端口来创建端口映射。
NAT 设备将维护这些映射组成的表,并将该端口的映射存储在表中。外部 IP 地址和端口就是该数据通信用于取代内部客户机 IP 地址和端口的公共 IP 地址和端口。
NAT 设备随即将来自客户机专用内部 IP 地址和端口的数据包的源字段转换为 NAT 设备的公共 IP 地址和端口,从而对这些数据包进行转换。
然后,数据包将通过外部网络发送出去,并最终到达目标服务器。
图 2:出站数据包转换的示例。
服务器上
当服务器接收到数据包时,它认为自己是在和一台具有可全球路由 IP 地址的计算机进行通信。它会利用自己源字段中的 IP 地址和端口将响应数据包定向到 NAT 设备的外部 IP 地址和端口。
NAT 设备上的输入数据包
NAT 从服务器那接收到这些数据包,然后将数据包与其端口映射表进行比较。如果 NAT 发现某个端口映射的远程主机 IP 地址、远程端口、外部端口及网络协议与输入数据包的源 IP 地址、源端口、目标端口和网络协议匹配,NAT 就会进行反向转换。NAT 将把数据包目标字段中的外部 IP 地址和外部端口替换为客户机的专用 IP 地址和内部端口。
然后,NAT 将内部网络上的数据包发送给客户机。然而,如果 NAT 找不到对应的端口映射,它就会丢弃输入数据包并中断连接。
NAT 的作用是,客户机将能在全球 Internet 上与专用 IP 地址进行通讯,而应用程序或客户机却无需做任何额外的工作。这意味着应用程序不必调用额外的 API,客户机也不必执行附加的配置。在这种情况下,NAT 对客户机和服务器应用程序来说都是透明的 - 所有对象都正常工作。
但是,并非所有网络应用程序都使用能与 NAT 协同工作的协议。这就是问题的所在。
NAT 与应用程序之间的常见问题
如果客户机在开始连接和接收回复时都使用同一端口,则让客户机利用 NAT 来共享单个可全局路由的 IP 地址不会有什么问题。但是,许多应用程序所用策略的假定条件在 NAT 设备用于连接 Internet 时都不成立。这里将讨论其中一些问题。
内部网络上的服务
很多网络服务或服务器假定,如果建立监听套接字,则 Internet 上的所有客户机都可以与之联系。如果在网络的边界上有 NAT 设备,为了将通信引入到内部网络服务,NAT 需要存在端口映射。但在网络边缘上有 NAT 设备时,NAT 却要求进行端口映射,以便将输入通讯转发给内部网络上的服务。因此,该服务仅对专用网络上的客户机有效。它对于 Internet 其余部分而言不可用。
该问题最常见的解决办法是手动配置端口映射,使 NAT 设备将定向给 NAT 特定外部 IP 地址和端口的通信转发给该服务所用的内部 IP 地址和端口。
利用该端口映射,服务可以接收输入数据包,从而使服务可被专用网络外部的客户机所使用。建立端口映射之前,网络是断开的。
手动配置映射通常很复杂,为了正确配置映射需要较有经验的用户。因此,除非是联系自己宽带 Internet 服务提供商、PC 制造商、零售商或 Internet 网关制造商的客户服务中心以尝试找到问题的根源及解决方案,否则许多一般用户或小型企业用户将无法使用所需的应用程序或服务。上述情况还会造成映射的不严格:许多外部客户机都可以使用该映射来连接服务器。
嵌入地址或端口
有些网络应用程序假定客户机所分配的 IP 地址和端口将始终可进行全局路由,并可直接在 Internet 上使用。许多情况下,它们属于 IETF 保留地址范围内的专用 IP 地址。应用程序会在发送给服务器的数据包的负载中包含该专用 IP 地址或端口。服务器可以将该嵌入地址用作联系客户机时所用的地址。
如果服务器试图用嵌入 IP 地址和端口进行回复,而非 NAT 提供的映射地址和端口,系统就会丢弃该数据包。这是因为嵌入 IP 地址是无法路由的。如果网络应用程序能找到 NAT 设备并检索到所要使用的外部 IP 地址和外部端口映射,应用程序就可以在数据包中嵌入正确的信息。
使用分散套接字的应用程序
还有一些网络应用程序使用端口 "X" 上的套接字向服务器或对等计算机发送通讯信息,然后等待将服务器的通讯信息接收到端口 "Y" 的独立监听套接字上。NAT 将监视输出通讯并为端口 "X" 创建端口映射,但并不对寻址到端口 "Y" 的返回数据包进行端口映射。寻址到端口 "Y" 的输入数据包将被丢弃。
需要端口可用
有些网络协议假定始终有可全局路由的已知端口可用。当多个客户机共享 IP 地址时,每次将只有一个客户机能使用已知端口。例如,每次只有一个 Web 服务能使用本地网络上的端口 80。如果不是这样,NAT 设备将无法确定外部请求所适用的客户机。即使在配置端口映射的用户的帮助下,如果从本地网络的外部能找到多个客户机,也必须采取某些特殊的措施。
多个 NAT
对于客户机位于一个 NAT 后面的 NAT 的后面这个问题已经超出了本文所涵盖的范围。
对用户和行业的影响
上一段介绍了与 NAT 穿越有关的技术问题。从用户的角度讲,它所造成的影响比较简单:人们再也无法使用受 NAT 干扰的服务或应用程序。
现在,大多数用户甚至没有意识到自己已成为这种 NAT 问题的“受害者”。他们只是知道,当试图玩多人游戏或者使用对等应用程序 (例如进行实时通讯) 或其他某些应用程序时,却无法玩或无法使用。他们可能会在 PC 上看到类似“无法连接”等的错误消息,或者在试图使用应用程序时,程序却出现故障。
有时,具有拨号调制解调器 Internet 连接的用户在使用拨号调制解调器时不会出现上述问题。但当用户使用宽带服务并将 DSL 或电缆调制解调器设备与 NAT 一起使用时,却出现故障。在进行快速 Internet 连接的情况下,这些用户尤其会受到 NAT 问题的困扰:它们会突然导致用户无法玩游戏或使用其他服务。
这导致了用户的不满,矛头指向 PC 生产商、ISP、Internet 网关提供商等等。通常,用户并不知道问题的根源,而技术支持人员也并不总能知道如何通过电话解决这些问题。
这已不仅是用户的问题。它也成为向用户提供产品和服务的制造商的问题。用户在试图解决这些由 NAT 引起的问题时会拨打支持电话,而这部分费用会减少制造商或零售商的利润,甚至使其无利可图。这些问题会导致用户对试用服务的不满,从而使某些用户降低了对后续的新服务或新应用程序的兴趣。因此,NAT 会妨碍其他创新产品/服务的推出和使用。
鉴于上述因素,解决 NAT 问题已成为业界的一项重要任务。
什么是“NAT 穿越”?
“NAT 穿越”是这样一组功能:它允许网络应用程序能明确自己位于 NAT 设备的后面,获得外部 IP 地址,并将端口映射配置为将 NAT 外部端口的数据包转发给应用程序所用的内部端口,而所有这些都是自动完成的,因此用户不必手动配置端口映射或其他类似的方面。
相对与目前所用的、面向特定应用程序的其他方法而言,这对于解决由 NAT 引起的连接问题确实是一种更为全面的解决方案。目前使用的那些专门解决方案有的要求用户具有一定的技术知识,有的要求应用程序开发人员或 Internet 网关提供商进行专门的开发工作,也有的则对二者都要求。
虽然 NAT 穿越可以解决一些 NAT 问题,但它不是万能药,不能解决所有问题。尽管如此,在提高用户满意度、减少用户支持呼叫的次数和支持新的、具有创造性的服务和应用程序方面,这种自动化的 NAT 穿越代表了非常重要的一步,尤其对于家庭网络环境而言。
NAT 穿越应视为一种在需要时使用的处理机制,而非在所有情况下都发挥作用。在 IPv6 中,每个客户机都具有可全局路由的 IP 地址,因此已不再需要 NAT 及 NAT 穿越。就 IPv6 能在多长时间得到普遍部署这一问题,有各种不同的预测。在业界,包括 Microsoft,已投入巨资推进 IPv6,但在现在及未来的几年内,本文后面所述的 NAT 穿越解决方案对于希望解决 NAT 问题的一般用户和小型企业用户而言却意义非凡。
NAT 穿越操作
“NAT 穿越”依赖于作为通用即插即用 (UPnP) 论坛规范组成部分的发现和控制协议。UPnP 论坛有一个工作委员会主要负责定义 Internet 网关设备的控制协议并定义这些设备的服务。
支持 Internet 网关设备控制协议基本元素的 Internet 网关设备可向局域网上的控制点声明自己的存在并发布 XML 描述文档。利用这些 XML 描述文档,控制点就能了解用于确定 Internet 网关是否支持 NAT、获取 NAT 的外部 IP 地址及创建端口映射时需要调用的 UPnP 操作。
Windows 中的“NAT 穿越 API”对直接使用 UPnP 的要求进行了提炼,可提供用于检测、管理和配置 NAT 设备的接口。
NAT 穿越 API
当网络应用程序需要检测是否存在 NAT 设备并调整该设备的行为时,该应用程序可以使用 Windows 中提供的“NAT 穿越 API”(完整记录在 Platform SDK 中) 来实现下列功能:
判断 NAT 是否存在
获取 NAT 的外部 IP 地址。
获取特定外部端口的静态端口映射信息 (如果已映射)。
添加静态端口映射 (除非已分配外部端口)。
启用或禁用特定的端口映射而不删除
编辑静态端口映射的界面友好描述
删除静态端口映射
获取局域网静态端口映射的列表。
利用这些功能,应用程序可以解决许多因 NAT 而导致的问题。请注意:Windows NAT 穿越 API 目前仅在有限的时间内支持端口映射,否则将称为静态端口映射。
Windows XP 中的 NAT 穿越 API
默认情况下,Windows XP 中将安装 NAT 穿越 API。这些 API 也可安装在运行 Windows Me 和 Windows 98 的计算机中,方法是使用 Windows XP CD 上一个名为“网络安装向导”的工具。为提供附加 XML 解析器支持,“NAT 穿越 API”还要求安装 Internet Explorer 6.0。
Windows 2000 目前不支持“NAT 穿越”。
Internet 网关中支持 NAT 穿越
Internet 网关对 NAT 穿越的支持是通过支持 “通用即插即用论坛” 所定义的 Internet 网关设备 (IGD) 规范而实现的。网关制造商还应注意到:Windows 中的 NAT 穿越 API 对 IGD 进行下列假定:
IGD 每次仅声明一个外部接口。尽管在技术上允许 Internet 网关设备声明多个外部接口,但“NAT 穿越 API”却只使用第一个。
IGD 支持允许任何远程 IP 地址将数据包发送给内部客户机的端口映射。
IGD 支持具有广播地址 (列为客户机) 的端口映射
IGD 支持 NAT 外部端口数与客户机内部端口数不同。
IGD 将声明版本号 1。
静态端口映射 (或称持续时间设置为无限的端口映射) 将无限期存在。即使是重新启动系统、更改 IP 地址或是服务器上存在客户机,都无法去除静态端口映射。
本文写作的过程中,几个业界领先的制造商已经宣布在 2001 年提供支持这些 UPnP 方法并且能与 Windows NAT 穿越 API 协同使用的 Internet 网关设备。对于业界和用户而言,这都是向前迈进的有意义的一步。
随着越来越多的 Internet 网关设备提供商认识到使用 UPnP 解决上述问题所具有的优势,随着更多一般用户和小型企业用户开始意识到与 NAT 有关的问题及这些支持 UPnP 的 NAT 穿越解决方案的强大功能,为 NAT 穿越提供 UPnP 支持有望成为此类设备的必备功能或入市前提。
Internet 网关制造商应加入 UPnP 论坛,了解如何使自己的 Internet 网关设备符合 UPnP 标准。
应说明的是:Windows XP 上的“Internet 连接共享”支持 UPnP IGD 标准 0.9 版。预计版本 1.0 将与版本 0.9 兼容。
应用程序怎样使用 NAT 穿越
应用程序使用“NAT 穿越”的方式与多个因素有关,包括端口映射期望的生存期及端口是否用于多个客户机或服务。应用程序应清除自己创建的所有静态端口映射,以避免出现孤立映射及端口被其他应用程序占尽的情况。
如果应用程序是一种网络服务 (例如 Web 服务器),并在生存期内要求使用已知端口,它的安装程序就可以使用 “NAT 穿越 API” 来配置一个静态端口映射。假定其他应用程序、网络管理员、网络拓扑结构都维持原状,而清除机制也保持映射不变,则外部客户机就能在服务生存期内连接该服务。应用程序卸载服务负责删除这个映射。如果出现崩溃,即使服务已不存在,静态端口映射也仍将存在。如果外部 IP 地址发生变化,则静态端口映射将自动获取更改的内容。
如果应用程序并不始终运行,或者对网络维护其静态端口映射的信任度降低,它就可以在每次启动时保留某个已知端口,并在每次关闭时恢复资源。这一点可通过运行某个并行脚本来实现。作为添加和删除端口映射的替代方案,可以让应用程序根据需要启用和禁用映射。应用程序还可以始终保留静态端口映射,且只在每次启用时刷新映射。
同样,如果外部 IP 地址发生变化,则静态端口映射将自动获取更改的内容。
如果专用网络上不同客户机的多个应用程序使用同一内部端口号,应用程序就会要求进行修改,以支持多个客户机的运行。只有单个客户机能使用外部端口映射的内部端口号。此处建议让第一个客户机使用。其他客户机应请求内部端口数不同于外部端口数的非对称端口映射。
有一种特殊的情况:多个客户机可监听同一外部端口,而唯一的目的是被远程主机发现。输入数据包可以转换为使用内部客户机 IP 地址的广播地址,而非特定的客户机地址。监听该端口的客户机可通过启动自己与远程主机之间的连接而予以回复。建议不要普遍使用这种方案,因为到该地址的输入数据包将被网络上的所有客户机接收,并会反过来对它们造成影响。
如果服务需要短期监听某个随机端口,它应在应用程序中请求一个静态端口映射,而非使用脚本。服务结束时,应予以清除 (删除映射)。应用程序应保留一份自己特有端口映射的记录。这样,如果应用程序在崩溃时没有关闭映射,就可以在下一次启动时检索出清除端口映射所需的必要信息。
如果应用程序离开网络时没有清除其端口映射,则该映射就会保留下来,而清除任务就落在用户的身上。目前 Windows 中尚没有清除机制,这是因为很难判断应用程序不再使用映射的时间。NAT 穿越的局限
尽管“NAT 穿越”可以解决与通过 NAT 设备进行连接时有关的多种问题,但还有“NAT 穿越”无法解决的问题及由其引起的问题。这些问题包括:
NAT 穿越使用开放式信任模式。这意味着专用网络上的所有应用程序都能访问 NAT 上的所有端口映射。尽管这样可以增加一些管理方面的灵活性,但应用程序也就失去了对其映射的唯一占有权。
应用程序将负责解决冲突。如果应用程序尝试映射某个已映射给其他客户机的端口,它就应负责查找另一个端口或改写应用程序。
NAT 穿越无法解决在 ISP 分发专用地址和使用 NAT 进行客户机连接方面的问题。这种情况下,NAT 位于 Internet 网关设备的外面,实际上位于服务提供商网络的内部。如果客户机网络上的 NAT 位于另一个同类 NAT 的后面,家庭或小型企业中的 NAT 穿越就会出现故障。因此,建议 Internet 服务提供商不要在自己的网络内部署 NAT。
应用程序获取 NAT 穿越时并非毫无代价。它们必须同时进行修改以调用 API,或者随带脚本以提供解决方案。这对于大多数开发人员而言仍在可控制的范围内,尤其是考虑到将这些 NAT 穿越机制并入应用程序后,应用程序就能自动与多种 Internet 网关设备协同使用。
使用完端口映射后,应用程序负责清除工作。静态映射会无限期存在,最好用于打算在整个应用程序生存期内监听知名端口的服务。
提供 NAT 的 Internet 网关必须支持通用即插即用 Internet 网关设备规范 (至少为版本 0.9)。
结论
NAT 是得到 IETF 认可的解决方案,针对的是 IPv4 名称空间耗用问题。使用 NAT 的 Internet 网关经常用于家庭和小型企业。之所以使用它们,是因为它们价格便宜,易于管理,无需用户安装特殊的软件。
使用 NAT 的不足在于会破坏许多聊天、多人游戏和对等应用程序。这是因为它们的网络协议对网络体系结构所做的假定已不成立。
“NAT 穿越”为应用程序提供了一条查找 NAT 设备、发现可全局路由的共享 IP 地址并配置静态端口映射以解决某些连接问题的途径。NAT 穿越解决方案无法解决与 NAT 有关的所有问题,但可以缓解部分问题。
本文的主要结论是:
Internet 网关设备制造商应在自己的设备中支持 UPnP,从而支持“NAT 穿越”。
网络应用程序开发人员应使用 Windows NAT 穿越 API 来检测 NAT 的存在,并在必要时允许其应用程序经过 NAT。
用户应使用支持 UPnP 和“NAT 穿越”的 Internet 网关设备,以确保最佳的应用程序性能。
DSL 和电缆调制解调器的服务提供商应指定、销售和租赁为 NAT 穿越提供 UPnP 支持的 Internet 网关设备。
在 IPv6 最终消除 NAT 之前,某些形式的 NAT 穿越仍会继续存在。