韵达快递一直不派送:TCP穿透NAT和防火墙的特点与测评 [中文版][个人翻译]

来源:百度文库 编辑:偶看新闻 时间:2024/04/30 14:38:27

[摘要]近些年,标准化社区已经开发出一些UDP穿透NAT/防火墙的技术(也就是,在NAT之后的主机之间建立UDP流)。然而,由于TCP连接建立的不对称特点,TCP的NAT穿透要困难的多。最近,研究者们提出了多种TCP穿透NAT的途径,然而,这些方法中,成功的都依赖于NAT对各种TCP(和TCMP)包的序列如何响应的。本文对TCP穿透主流商用NAT产品的主要技术进行了首次深入、广泛的研究。我们开发了一套公开、有效的软件测试套件用来测定NAT对各种独立探测以及完整的TCP连接建立的响应。我们在实验室测试了16个NAT产品,在公网上测试了93个家用NAT产品。根据这些测试结果,如同NAT产品的市场宣传那样,我们评估了家用网络中NAT穿透成功的可能性。本文的另外一个出发点,就是可以给TCP穿透NAT协议的设计和NAT/防火墙行为的标准化工作给与指导,包括IPv6过渡期间IPv4与IPv6之间穿透NAT的鉴定。
绪论
 NAT和防火墙通过阻止外部主机主动连接一个受保护的内网1主机的方式破坏了IP连通性模型。如果两个终端都被他们各自的NAT或防火墙保护着,由于发起连接的终端在另一终端的NAT2之外,通常的TCP连接是不能建立的,除非各自的防火墙安全策略允许这样的连接。例如,防火墙策略是这样的:内部主机可以发起TCP连接,而且两个主机都希望发起连接。近来的研究工作已经集中在不使用代理或隧道来建立TCP连接。通过在NAT上设置必要的连接状态,并仔细、巧妙地交换TCP包的方式来建立TCP连接,确实很轻巧。然而,并不是公网上的所有NAT都用同样的方式响应,所以,造成这些方式在很多情况下失败。理解NAT的这种行为,测定他们对Internet中普遍连通性的原始目标的偏移有多少,对于把他们干净利索地集成到这种架构中是至关重要的。
 今天的Internet架构于TCP/IP设计之初的环境已经大不相同。防火墙和NAT经常是的建立一个连接成为不可能,即使连接没有违反任何安全策略。例如,通过隐藏在一个NAT后面或配置他们的防火墙阻止外入的SYN包,Alice和Bob可能都不允许未授权的连接。然而,当Alice和Bob都同意建立连接的时候,如果不重新配置他们的NAT,他们也没有办法建立了,因为Alice的SYN包会被Bob的NAT阻止,Bob的SYN包也会被Alice的NAT阻止。虽然如此,但NAT和防火墙已经成为网络架构中的永久一部分了,而且,很长一段时间内,仍将会是。即使IPv6已经在全球展开,但在过渡期间,IPv4与IPv6之间的NAT仍将是必须的,而且,为了安全,IPv6防火墙仍将是必须的。因此,使得NAT后面的同意连接的主机之间能够彼此通讯的机制,是必须的。
 通过STUN,已经解决了UDP方式的穿透问题。使用STUN,Alice发送一个UDP包给Bob,尽管这个包被Bob的NAT阻止,但却使Alice的NAT创建了一个本地状态,该状态允许Bob的回应包到达Alice而不被Alice的NAT阻止。然后,Bob发送一个UDP包给Alice,Alice的NAT认为这个包是第一个包的网络流的一部份,所以路由它通过;同样,Bob的NAT把第二个包(Bob发给Alice的包)当作一个连接发起,因此创建本地状态并路由Alice的回应包。流行的VoIP应用程序Skype就是使用的这种方式。不幸的是,建立TCP连接要比这复杂的多。一旦Alice发送了她的SYN包,她的操作系统就如同她的NAT一样,期望从Bob接收到一个SYNACK包作为回应。然而,由于Alice的SYN包被Bob的NAT阻止,Bob的协议栈根本不会产生SYNACK。解决这个问题的建议工作很复杂,因为广域网中与NAT的交互很难理解,而且他们解决该问题建议的可行性也是未知的。因此,像Skype中文件传输模块这样的应用程序,就是用了与UDP类似的受限协议。虽然这种途径也许可以工作,但我们相信,无论如何,只要可能,应用程序使用本地操作系统的TCP协议栈是很重要的。这是避免增加协议栈复杂性的一部份,而且更重要的是,这么多年以来,为了高性能和拥赛控制,TCP协议栈已经被仔细优化。
 全部工作可以归结为四点:第一,我们鉴别并描述了对TCP穿透NAT重要的全部NAT特点;第二,我们测定了多种建议解决途径中P2P的TCP连接的成功率和各自的特点;第三,基于这些测定,我对这些建议途径提出了改进;第四,我们提供了通用的软件工具,可以用来测定NAT的发展以及P2P应用程序中TCP穿透NAT的基础。总而言之,我们对穿透NAT的成功率与实现的复杂性之间的内在均衡为应用开发者们提出了建议。最后,我们的结果可以为NAT和防火墙的标准化进程提供指导,使NAT和防火墙具有更好的穿透性,但又不失原有的安全策略。
 本文后面的内容安排如下:第二部分讨论了建议的TCP穿透NAT的方法;第三部分和第四部分说明了我们测试NAT的组织和观察到的NAT行为;第五部分分析了端口预测;第六部分分析了P2P中TCP连接的建立;第七部分讨论了相关的工作;第八部分对全文进行了总结。
TCP NAT-Traversal
 这部分我们讨论TCP穿透NAT的方法,这些方法在最近的文章中被提出。所有这些方法中,两个终端都发起一个TCP连接。从每个主机向外发出的SYN包在自己的NAT上创建必要的NAT状态。然后,每种方法都通过本节描述的不同机制,把两个TCP的尝试连接转换为一个单一的连接。这些原始SYN包被发送的目的地址和端口,通过端口预测决定。端口预测允许主机在发送外出的SYN之前猜测NAT为一个连接的映射,详细方法稍后讨论。这些方法也需要两台主机之间相互协调。比如通过第三方或UDP/STUN会话等这样的连接代理作为辅助通道,就是一种技巧。一旦建立了直接的TCP连接,辅助通道就可以关闭了。协调机制在不同的NAT中触发不同的行为,这也导致了在很多情况下,所建议的方法会失败。而且,终端也可能处在连续的多个3NAT后面。这种情况下,所观察到的行为是整个通路上所有NAT和防火墙行为的复合。简单的讲,我们应该明白,这里的NAT是指复合的NAT/防火墙。
2.1 STUNT
 在参考文献[9]中,作者提出了两种穿透NAT的方法。第一种方法,如图-1所示,终端双方都主动发送SYN,且SYN的TTL4要足够大,大到SYN包能穿过他们各自的NAT,但TTL又要足够小,小到穿过各自的NAT后就过期而被网络丢弃。通过侦听经过RAW-socket或PCAP向外发送的SYN,终端可以得知初始TCP的序号。终端双方把各自的序号告诉都能抵达(连接)的STUN Server,紧接着,STUN Server通过设置匹配的序号构造一个SYNACK来欺骗双方(双方都认为该SYNACK是对方回应的)。完成TCP握手任务的ACK按照正常方式穿过网络。这种方法有四个潜在的问题:第一,它需要终端确定一个TTL,该TTL足够大,大到可以穿透自己的NAT,但又要足够小,小到不能到达对方的NAT;第二,作为SYN包的回应,比TTL优先的ICMP错误是可能产生的,而且,也可能被NAT认为是致命的错误;第三,NAT可能改变初始SYN的TCP序号,这样就可能导致基于原始序号的欺骗SYNACK到达NAT时,被当作窗口之外的包;第四,它需要一个第三方为一个任意地址产生一个欺骗包,而该欺骗包很可能被网络中各种各样的进出过滤器丢弃。这些网络和NAT实例在表-1中总结。
 参考文献[9]中提出的第二种方法,与参考文献[5]中提出的方法类似,只有一个终端发出一个低TTL的SYN包,接着该发送者取消该连接企图,并在相同的地址和端口创建一个被动的TCP套接字。然后,另一个终端初始化一个正常的TCP连接,如图-1(b)所示。与第一种方法一样,终端需要挑选一个恰当的TTL,而且NAT也不能把ICMP错误当作致命错误。它也需要NAT在一个向外发的SYN后,接收一个向内发的SYN,但包的序号也不是普通的那种。
 
2.2 NATBlaster
 参考文献[3]中,作者提出了一种与第一种STUN方法类似但取消了IP欺骗需要的方法(如图-1c所示)。每个终端发出一个低TTL的SYN,并记住协议栈所使用的TCP序号。与前面的类似,SYN包在网络中被丢弃。两台主机之间交换各自的序号,并且每台主机手工产生一个对方期望收到的SYNACK包。手工产生的包通过RAW socket注入网络。然而,这并不等同于欺骗,因为该包中的源地址与注入该包的终端地址匹配。一旦收到SYNACK,ACK就被交换了,从而完成了连接建立。与第一种STUNT方法一样,该方法也需要终端准确地选择TTL值,也需要NAT忽略ICMP错误和NAT改变SYN包序号的失败。而且,(该方法)也需要NAT允许一个外发的SYN之后紧跟一个外发的SYNACK——非正常的另一个序号的包。
2.3 Peer-to-Peer NAT
 参考文献[6]中,作者利用了TCP规范[13]中定义的同时打开方案。如图-1d所示,两个终端都通过发送SYN包来创建一个连接。如果SYN包在网络中交叉(穿过),这两个终端协议栈都用SYNACK包应答从而建立连接。如果在对方的SYN包离开它的NAT之前,一个终端的SYN包到达该终端的NAT而被丢弃,那么,第一个终端的协议栈会在TCP同时打开之后而结束(关闭),而另一个终端则会按照正常流程打开。接下来的情况,链路中的包看起来像第二种STUNT方法,没有底TTL,也没有相关的ICMP。然而,该方法并没有用端口预测,如果使用的话,该方法可以从中获益。与第二种STUNT方法一样,该方法需要NAT允许在一个外发的SYN之后紧跟一个内发的SYN,而且,该方法需要终端在一个循环中不停的尝试重连,直到超时。如果不是SYN包被丢弃,而是NAT返回一个TCP RST,那这种方法将陷入包泛滥的境地,直到超时。
2.4 实现
 我们在Linux和Windows上实现了上面所述的所有方法。我们还开发了一个Windows设备驱动,它实现了这些方法所需要的但Windows本身不支持的功能(函数)。第一种STUNT方法,无论是在Windows下还是在Linux下,都需要超级用户特权来监听链路中的TCP SYN包并获取其序号。为了设置第一个SYN包的TTL,我们在Linux下使用了IP_TTL套接字选项,在Windows下使用了我们的驱动。我们还实现了STUNT Server,并把它部署在ISP后面,为了欺骗任意地址,该ISP不进行外出过滤。虽然该Server可以欺骗大部分SYNACK,但是,如果源和目标在同一个管理域或者该域使用了准入过滤,它的欺骗SYNACK就不成功了。等可能的时候,我们在这种域中安装一个另外的STUNT Server。第二种STUNT方法需要该驱动来设置Windows下的TTL。NATBlaster方法需要超级用户特权来获取SYN的序号并通过RAW socket注入手工创建的SYNACK。由于Windows XP SP2中引入的限制,该方法需要我们的驱动来注入(SYNACK)包。P2PNAT方法需要操作系统支持TCP同时打开,Linux和Windows XP SP2支持TCP同时打开,但SP2之前的Window XP都不支持。在Windows XP SP1以及之前的版本中,我们的驱动增加了TCP同时打开的支持。表-1总结了这些实现结果。

我们发现,在Windows下设置TTL是有问题的,因此,我们考虑了不使用它的后果。如果TTL不消减,一个主机发送的第一个SYN,在对方的SYN离开其NAT之前到达对方的NAT,那对方的NAT可以悄无声息地丢弃该入站的包,也可以返回一个ICMP不可达错误或一个TCP RST/ACK。无论怎样,回应可能触发该方法中未说明的发送者NAT以及操作系统栈中的转变。如果发送到对方的SYN的TTL不被消减,该SYN可能到达预期的目标并触发无法预料的转换。这种行为对于最终目标可能是有利的,例如,如果它触发一个TCP同时打开;如果它扰乱了协议栈或NAT,则它是有害的。我们实现了上述方法的修正版,它不使用低TTL。表-1列出了与修正方法对应的网络和实现结果。

实验安装
 我们定义了STUNT client-server协议,该协议既可以测试NAT/防火墙的行为,也可以帮助NAT后面peer之间建立TCP连接。完整的协议描述请参考文献[7]。我们的测试程序实现了该协议,测试程序包括一个client组件和一个server组件。如图-2所示,client运行在一台一个或多个NAT后面的主机上,而server则在他们之外。该STUNT测试client侦测client和server之间的所有NAT和防火墙的合成行为。虽然测试client和server都需要超级特权来分析链路层的raw socket,但为了降低功能损失并保证client之间的交互,可以降低(取消)该需求(超级特权)。而且,该server至少需要两个网络接口来正确区分各种NAT所用的端口分配算法。该client的测试性能以及由此推演的NAT特点在后面的第四部分描述。
我们用该client测试了实验(表-2)中16个NAT中多种集合。这些NAT包括了我们在美国的网上商店所能找到的各种品牌NAT。这些测试NAT也包括了当前流行操作系统所实现的软件NAT。在每个实验测试中,client主机是该NAT内的唯一主机,server与该NAT的外部接口在同一以太网段内。Client主机被设置为只由测试程序产生网络通信,而不产生任何其他的网络通信。而且,为了这些实验测试,我们也测试了其他NAT设备。这样做的主要原因是把我们的测试软件暴露给更广的情况范围,而不仅仅是我们在实验室能够重现的情况,从而提高它的鲁棒性,也增强我们对它操作性的信心。而且,还提供了一个示例,虽然小,但可以用它测试出实际看到的NAT是什么类型。为此,我们请求家庭用户运行该测试client,共测试了计算机系、Cornell的学生以及其他大学所用的93个家用NAT,而且,测试通信是该client主机与NAT之后的其他主机之间的典型网络活动,包括web浏览、即时消息、p2p文件共享以及email等。测试数据告诉我们,NAT品牌与新旧模块和固件是混合在一起的。当然,必须承认,在NAT和相关小用户的选择上是存在偏见的,他们大部分在美国的东北部。这种差异在表-3中很明显,我们示例中观察到的品牌普及率在“Sample”列中,Synergy Research Group调查的2005年第一季度的世界SOHO/家用广域网市场品牌份额在“Market Survey”列中。特别要说明的是,Buffalo科技和Netgear(的NAT)在我们的示例中表现一般,其他品牌的(NAT的市场份额)明显更高。家用NAT测试的完整列表请参考文献[8]。NAT TCP特点
 这一节,我们确定不同NAT怎样影响TCP的NAT穿透方法。根据NAT的行为,我们划分了五个类别,即NAT映射、终端包过滤、过滤应答、TCP序号预留和TCP定时器。每个类别的分类和NAT能够接收到的值之间的关系如表-4所示。我们使用STUNT的测试client和前面第三节中描述的server对实验室中的16个NAT和世界各地的93个NAT进行了分类。完整的测试结果以及更广范围的分类集合在参考文献[8]中有描述。
4.1NAT映射
NAT为每个基于源和目的IP和端口的TCP连接选择一个对外映射。在某些条件下,有些NAT会重用已经存在的映射,而有些则每次都分配新的映射。NAT映射类别就捕捉这些映射行为的不同。这对于那些企图穿透NAT的终端来说非常有用,因为这可以让他们基于之前的连接来预测一个(新)连接的映射地址和端口。根据参考文献[15],对于UDP来说,我们知道,有些NAT为那些从同一个源地址和端口产生的所有连接,总是分配一个固定的地址和端口。用STUNT的client,我们测试了TCP的类似行为。如图-3和表-5所示,该(STUNT)client快速连续从固定的本地地址和端口a:p向不同server地址和端口建立了12个连接。每个连接在下一个连接产生之前关闭。Server把其感知到的映射地址和端口返回给该client。测试选择了多个不同的本地端口重复了多次。
  

Table 5: NAT Mapping test behavior observed. Nat1–5 show the 5 different mapping patterns that are observed in practice. Nat6 is a possible mapping pattern that has not been observed in our sample set.

从表-5中的NAT1——NAT6的端口映射中,我们注意到几个截然不同的模式。假设每个NAT为第一个连接分配的映射叫做A:P,只要该client新连接的源地址和端口与第一次连接的相同,NAT1就一直重用该映射。我们把这种行为归类为NB:Independent,因为映射只由源地址和端口决定,而独立于目的地址和端口。这与参考文献[15]中扩展到包括TCP的“cone behavior”相同。只要新连接的源和目标的地址和端口与第一次连接的匹配,NAT2就重用该映射。这种NAT杯归类为NB:Address and Port1,因为目标地址和端口都影响映射。下标“1” 表示两个新映射之间的差,用δ表示,就是1。参考文献[17]中表明,对UDP来说,许多NAT的δ是固定的,通常是1或2。我们发现NAT对TCP也有同样的特点,而且,我们所遇到的NAT,δ都为1。NAT3为每个新连接分配一个新的映射,尽管每个新映射的端口只比前一个(映射的)端口大1,即δ=1。我们把NAT3归类为NB:Connection1。与NAT3类似,NAT4为每个TCP连接分配一个新的映射,但两个并发映射之间却没有区分模式。我们把这类NAT归类为NB:ConnectionR,下标R表示δ是随机的。NAT5是NAT2的一个变种,在NAT5中,只要目标端口匹配就重用该映射,去除了源地址和端口(也匹配的条件)。NAT6也与此类似,只是用目标地址代替了目标端口的匹配。NAT5和NAT6各自被归类为NB:Port1和NB:Address1。NAT2~6呈现的对称行为参见[15]。
表-6给出了每种NAT的相关比例。第二列是我们测试了的16个NAT中按照特定类型归类的NAT个数。其中大部分是NB:Independent。唯一的一个NB:ConnectionR是OpenBSD中pf工具中实现的NAT。我们也发现我们的固件版本为5.13的Netgear RP614是NB:Connection1,而最近的NetgearNAT,如固件为5.3_05的MR814V2,则是NB:Independent。第三列则是估计的实验室之外的NAT行为。估计值是根据87个家用NAT样本按照各自的类型和品牌的比例进行计算的,并按照一个修正因子进行了缩放,以此来避免我们所选样本的偏见。每个品牌的修正因子都是表-3中的调查与观察的市场份额的比率。该修正因子用来增加评估结果中表现不好的贡献,降低表现太好的贡献。虽然我们的评估很好的反映了我们所期望的趋势,但我们也明白,在如今每年47%的工业变化率下,任何结果的正确性都不会持续太久。不过,我们评估出多数(70.1%)的NAT是NB:Independent类型的,几乎没有NB:ConnectionR类型的NAT。很大比例(29.9%)的NAT有对称行为,因此,更多的情况下,从同一个端口发出的多个连接将不被分配到相同的映射,所以,应用不得不使用后面描述的更成熟的端口预测技术。
4.2 终点过滤
NAT和防火墙都可能过滤寻址到某个端口的进入包,除非(这些包)满足一定的条件。如果那个端口上不存在NAT映射,NAT就会强制过滤掉包,所以,它就不能再前进。然而,如果映射已经存在,或者设备是防火墙的话,那就可能需要进入包的源地址和(或)端口与之前的外出包的目的地匹配。这些触发过滤条件的不同,是通过终点过滤分类捕捉的。STUNT的测试client通过连接(STUNT)server而首先设置NAT状态来决定(是否过滤进入包)的,然后再请求server从不同的地址和端口向已经映射好的地址和端口发起连接(请求),如图-4所示。
根据该测试所观察到的不同过滤行为如表-7所示。Nat1’接受所有三个SYN包。这种NAT允许进入的TCP连接与源地址和端口无关,只要路由该请求的必要状态存在即可。我们把这种NAT分类为有终点过滤行为,即EF:Independent。Nat2过滤所有进入包,因此需要进入的TCP报的源与创建映射的(TCP)连接的目的地址和端口都匹配。这种NAT的终点过滤被分类为EF:Address and Port。Nat3’和Nat4’允许与该连接目的地有相同地址或端口的包进入,但各自会过滤从不同地址或不同端口来的包。我们把这种终点过滤分别分类为EF:Address和EF:Port。我们发现,通常情况下,一个NAT的终点过滤行为与NAT的映射行为无关。参考文献[15]中定义的cone NAT的子类转换为如下:full cone就等于NB:Independent和EF:Independent;restricted cone对应于NB:Independent和EF:Address;port restricted cone与NB:Independent和EF:Port对应。Table 7: NAT endpoint filtering behavior observed. Nat10–Nat40 show 4 different filtering behaviors that are observed or inbound SYN packets after an internal host establishes a connection from a:p to B:Q with allocated mapping A:P表-8列出了实验室中16个NAT的终点过滤分类和估计的实验室之外NAT的百分比。估计是基于前面所述的市场调查来计算的。81.9%的NAT估计是EF:Address和EF:Port,而只有5.8%的是EF:Independent。这表明,大多数情况下,若要两台NAT之后的主机要建立连接的话,外发的SYN必须在进入包被接收前从每个终端发出。
4.2.1 TCP状态追踪
NAT实现一个状态机来追踪终端的TCP进展,并决定连接状态何时可以回收。虽然所有的NAT都能正确地处理TCP的三次握手,但并不是所有的NAT都正确地实现了TCP状态机的特殊情况,因而导致提前终止连接状态。通过为这些方法重复(发送)观察到的包顺序,STUNT的client和server测试了NAT/防火墙的实现如何影响TCP穿透NAT的方法。
 表-9列出了部分测试的包顺序。我们估计,13.6%的NAT不支持TCP同时打开,即通过一个进入的SYN紧跟在一个外出的SYN之后。这就影响P2PNAT方法,因为该方法需要至少一个终端要像第二种STUNT方法那样支持同时打开(TCP)。6.9%的(NAT)会在ICMP TTL短暂的超时错误后就过滤掉进入的SYNACK包。与此差不多数量的NAT会在ICMP之后丢弃进入的SYN,但如果没有错误,则会接受该SYN。这种行为影响所有要设置SYN包低TTL的方法。大部分NAT(28.1%) 接受进入的SYN包,即使创建连接状态的SYN包遇到了严重的TCP RST(错误),这就减轻了欺骗RST的问题,尽管有些方法可对付欺骗RST问题。表中没有提到的是NATBlaster方法中需要的SYN-out和SYNACK-out的顺序。由于Windows XP SP2引入的限制,我们没有全面的测试这种情况,然而,在实验室,我们发现D-Link NAT(DI-604)就不支持它(SYN-out和SYNACK-out顺序)。
4.2.2 过滤应答
当一个进入包被NAT过滤后,NAT可以选择只是安静的丢弃该包,或者通知发送者。据估计,约91.8%的NAT只是简单地丢弃这些包,而没有任何通知。其余的NAT会为冒犯的包发送回一个TCP RST确认的错误信号。
4.3 包破坏
NAT改变外发包的源地址和端口以及进入包的目标地址和端口,而且,他们需要转换出ICMP有效负载中封装报的地址和端口,从而终端能够使ICMP与他们各自的传输套接字匹配。我们的样本集合中的所有NAT,要么正确地转换ICMP,要么过滤ICMP包,这些被过滤的ICMP包并不总是首先产生。一些NAT通过给外发包的序号加一个恒定的偏移值、给进入包的确认序号减去相同的偏移值来改变TCP序号。我们估计,约8.4%的NAT改变TCP序号。因此,有些情况下,那些需要离开NAT的包有初始序号的TCP穿透NAT的方法不能使用该终端SYN的序号来替代。
4.4 TCP定时器
NAT和防火墙不能随便控制状态,因为这样使他们很容易受到DoS攻击。相反,他们终止空闲连接,并删除崩溃或行为不轨终点的连接状态。而且,他们监控TCP标记,从由于FIN/FINACK交换或RST包而明确关闭的连接中恢复状态。他们可能允许一些过渡时间来使那些已经在传输中的包以及重传被传送。一旦连接状态不能被分配,任何基于该连接的后续达到的包都会被过滤掉。通常,NATs为这些情况使用不同的定时器,如图-5所示。在图中位置1和位置3处,使用一个短的定时器,分别用来终止还没有建立的连接或已经被关闭的连接。RFC1122规定,为了传递那些已经在传输中的包,终端机要等待4分钟(即2倍的MSL5),然而,大部分操作系统都只等待约1分钟。在图-5的位置2处,为已经建立的空闲连接,NAT使用一个常定时器,RFC1122中对应的规定是,在空闲连接上(两次)发送TCP-Keeplive包之间,TCP协议栈最少应该等待2小时。
 STUNT测试client检测了NAT定时器的实际情况与RFC规范的符合性。通过三个定时测试来分别检测每种情况。在第一个测试中,由client发起连接,但从server发出的SYNACK被延迟几分钟;第二个测试中,连接被建立后,空闲2小时,这时再从对面的server发送几个字节;在第三个测试中,连接建立,然后被关闭,但最后从server发出的ACK被延迟约一分钟。在各种情况下,如果引入延迟后,从server发出的包仍被传递到client,那对应的定时器就被称为保守派;相反就被称为激进派。我们估计,所有三种情况中,只有27.3%的NAT有保守定时器,而第二种情况则有35.8%的NAT有保守定时器。第二种情况,21.8%的NAT有非常激进的定时器,不活动时间不到15分钟,他们就终止已经建立的连接。这说明,应用不应该依靠空闲连接到维持(连接)打开太久(超过几分钟)。
端口预测
端口预测允许一台主机在连接被创建之前预测该连接被映射的地址和端口。因此,它(端口预测)允许两台主机与彼此的映射地址和端口发起连接,即使映射是在连接发起之后分配的。图-6显示了使用端口预测信息实现的一个典型的TCP穿透NAT的尝试。图中,我们假设A已经决定了它正使用的NAT类型。当clientA希望与clientB建立一个连接的话,A首先与STUNT server建立一个TCP连接,并获得映射(信息)。根据NAT M的NB类型,A预测出下一个连接的映射。B也作同样的事(连接STUNT server并预测出下一连接的映射),且A和B通过这种非直接的通道交换他们的预测信息。每个终端通过发送一个SYN包发起一个与对方映射地址和端口的连接。其余被交换的包设计为使两个TCP尝试协调为一个连接,如第二节描述的那样,不同的穿透方法,交换包的设计也各有不同。第一个SYN与目标连接的SYN之间的空隙可能是一个攻击点,这依赖于NAT M的类型。对于有些类型的NAT来说,如果NAT M后面的另一个内部主机A’在该空隙间发起另一个连接的话,M将会把A预测的映射分配给A’发起的连接。
 端口预测依赖于前面4.1节所探讨NAT映射类型。如果NAT是NB:Independent类型,那之后从相同源地址和端口发起的任何连接将会重用连接STUNT server的映射。因此,映射重用完全在client的控制之下,这种情况下,攻击点也就不存在了。然而,这种方法引入了一个潜在的问题,那就是在映射能够被预测之前,可能需要两倍的到STUNT server的RTT6。可能的优化是,我们注意到,大多数NAT通常分配一个与client所用的源端口相同的映射端口。我们称这些NAT为端口保留(型NAT)。处在这种NAT之后的client,即使没有首先与STUNT server建立连接,也能预测出被映射的端口,且有很高的概率。如果NAT不是NB:Independent类型,但有固定的δ,那么,与(STUNT)server连接之后立即发起的连接,将会有一个映射端口,该映射端口比server观察到的映射端口大δ。由于从连接到连接映射的变化,攻击点中的“流氓”连接的尝试能够窃取到该映射。而且,如果被预测的映射已经被使用,这种方法会失败,从而导致NAT的分配规则跳过它而直接到下一个有效的映射。
在STUNT测试client中,我们实现了端口预测,且在一小时内预测了83个家庭用户的映射。每分钟,测试client从一个源地址和端口发起一个到STUNT server的连接;然后,再用相同的源地址和端口向为该实验目的而安装的一台远程主机发起一个连接。测试client检查基于第一个连接映射所预测的映射与相对应的第二个连接实际观察到的映射(是否匹配)和NAT类型。如果,且只要他们匹配,端口预测就成功。当用户正常使用他们的主机和网络过程中,端口预测才被执行(才会激活(用的上)端口预测),这(正常使用主机和网络)包括web浏览器、email阅读器、即时消息以及在client主机和处在相同NAT后面的其他主机上运行的文件共享应用。88.9%的NB:Independent类型的NAT是端口保留的。这就说明对实现上述优化的交互应用来说是很有好处的。我们发现,81.9%的情况下,端口每次都被准确的预测,这包括所有的NB:Independent类型的NAT和37.5%的非NB:Independent类型的NAT,只有一种NB:Independent类型的NAT除外。对于剩下的其余62.5%的各种NAT来说,60个其他主机或应用中最少就有一个“窃取”了测试client自身预测的映射。其中一个特例中,处在NB:Connection1类型NAT后面的client主机被感染了病毒,病毒每秒钟产生多个随机地址的SYN包,从而导致所有的预测失败。另一个情况是,中途用户通过该测试发起一个VPN连接,导致所有后续的请求都被经过VPN发送,因而也就通过一个不同类型的NAT。这说明,长时间运行的应用可能会缓存一段时间的NAT映射类型,但必须及时更新使其有效。考虑所有情况的话,94.0%,也就是超过四分之三的端口预测是正确的。因此,一次尝试失败之后,如果应用简单地再尝试连接的话,很可能就成功了。
5.1 问题
端口预测有几个特殊例外的情况,在这些特殊情况下,端口预测可能失败。图-7中,当A尝试与C建立一个连接的时候,如果用STUNT server T来预测地址和端口的话,那A将会因获得NAT M的外部地址而不是NAT O的外部地址而告终。端口预测要求,client与STUNT server之间的(连接)线路与client和他所希望连接主机的大部分外部NAT之间的(连接)线路相同。因此,由于某些原因,为了连接C,A需要找到S。然而,如果A希望与B通信的话,且A和B都使用STUNT server S,那他们的端口预测尝试可能相互干扰,从而妨碍任何一方正确地预测端口。而且,即使端口预测正确,A和B也将由于使用O的外部地址而终止(连接)。这种情况被称为hairpin translation,因为从A发向B的预测地址和端口(这里是O的地址)的SYN将被传递到O,而O则需要把它(A发出的SYN)通过一个内部接口发送回去。不是所有的NAT都能正确处理hairpin translation,根据STUNT测试client所进行的测试,我们估计,这种错误行为高达72.8%。
 前面描述的端口预测技术不能处理NB:ConnectionR类型的NAT,这是由于连续的连接会被随机分配。参考文献[3]中提出了一种有趣的技术来处理这种情况,即在冲突发生前使用“生日悖论”来减少猜测的次数。该技术初始化439个连接,这样,被猜测的端口将有95%的可能性与其中的一个匹配。不幸的是,我们发现,有些NAT,如Netgear,限制挂起连接尝试的总数为1000,这就造成这种方法很快塞死NAT。幸运的是,几乎没有NAT证明NB:ConnectionR行为减轻(缓解)这个问题。
TCP建立
这一节,通过测试小范围P2P的TCP建立,我们估计各种NAT穿透方法的成功(几率),也给出我的经过。TCP穿透NAT方法的成功,依赖于两台终端机之间所有NAT的行为,也依赖于这些NAT后面其他主机的活动。第四节分析了相对独立情况下的各种NAT,而第五节则分析了竞争网络活动以及对端口预测的影响。结合这两节的结果,我们可以从数量上估计出每种NAT穿透方法的成功(几率)。关于TCP穿透方法的部署,我们作了如下的假设。我们假设STUNT server部署的足够广泛,可以确保每一对client都有一个STUNT server满足端口预测的要求,也能都欺骗从每个client的映射地址和端口出现的包。我们假设终端机的堆栈固定,因此终端上所有软件问题可以解决。最后,由于我们缺乏数据来模拟5.1节所呈现的情况,我们假设这种情况的贡献可以或略不计。作为这些假设的结果,我们的估计可能比较理想。
P2P的TCP建立依赖与两个终端的NAT。如果另一个(对方)终端的NAT可以预测,那一个不可预测NAT后面的终端仍能够建立一个连接;但如果另一个终端的NAT也不可预测,那就不能建立起连接。通过考虑实际观察到的所有NAT行为,我们评估了广泛的TCP连通性。图-8绘制出了各种TCP穿透NAT方法的成功率图。我们绘制两种STUNT方法(#1和#2),即参考文献[9、3、6]中提出的NATBlaster和P2PNAT的图示。而且,我们还绘制了STUNT#1和#2(方法)修改版的图示以及未使用低TTL的NATBlaster方法的图示。我们还绘制了使用端口预测的修改版P2PNAT方法的图示。这些(穿透)方法中,有些方法中的SYN包之间存在竞争条件,从而导致某些特定的NAT之间的欺骗包。浅灰色的柱表示当每个终端都有均等的机会赢得竞争情况下发送的成功率,这与终端双方同时调用方法相对应。深灰色的柱表示,当为了有利于成功连接而打破这种竞争时的成功率,这与双方各自调用(先后,也就是不同时)方法的情况对应,对于第一个调用,一个终端比对方稍微早一点点发起(连接),而对于第二个调用,则顺序刚好与此相反。在建立TCP连接中,只要任何一方的调用成功,该尝试(连接)就宣布成功。
 如图所示,原来所提出的方法中,P2PNAT和STUNT#1的成功率分别是44.6%和73.4%。通过每个终端再多尝试一次来打破竞争条件后,原来的STUNT#2方法把其成功率提升到了86.0%。与此类似,给P2PNAT方法增加端口预测,允许他处理对称NAT后,它的成功率增加到84.3%。令人惊讶的是,通过修改原来的方法,不使用低TTL,所有的方法都获益超过5%!打破竞争条件,因此获得的收益就是两种修改后的STUNT方法高达89.1%和88.7%的最好成功率,以及修改NATBlaster方法后85.2%的成功率。
不使用低TTL的SYN所获得的意外好处,可以这样解释。大部分NAT安静的丢弃掉第一个SYN包(4.2.2节),只有一少部分NAT过滤外发SYN包后(紧跟)的进入的SYN包(表-9)。因此,多数情况下,修改后的方法触发TCP同时打开,即使他们并不想这样(同时打开TCP)。相对于向产生TCP RST应答NAT所付出的惩罚来说,成功地TCP同时开发的赔偿更大。如果更多的NAT应答TCP RST包或者终端主机的操作系统不支持TCP同时打开的话,这种好处则被完全抹杀了。
6.1 实现
我们在一个P2P程序中用C实现了上述(穿透)方法。该程序运行在图-9所示的12个局域网连接的windows客户端上以及广域网连接的20个客户端中的大部分上。每个客户端随机挑选另一个客户端,并与其尝试建立TCP连接。所有的方法按照宣称工作(处理),只是不再讨论不用低TTL的STUNT#2和使用端口预测的P2PNAT。这是因为,我们发现STUNT#1和NATBlaster方法大范围广泛的部署是不切实际的,STUNT#1方法需要欺骗任意包的server广泛部署,而NATBlaster方法所需要的RAW套接字功能由于安全关系而在WindowsXP中被移除。
图-10显示了各种方法建立连接和在低延迟网络情况下报告失败所用时间的半对数图。成功连接的时间分布(图示中的x轴),P2PNAT方法中变化很大,而第二种STUNT方法则非常平和(一致)。这是因为P2PNAT方法重复发起连接直到其中一次成功或者出现超时,而第二种STUNT方法只发起一个连接。从图-10中的a图来看,大部分的连接是不成功的,直到21秒进入的连接尝试(才成功),因而为了取得先前测定的评估的成功率,需要(花费)大量超时时间。个别情况下,当端口预测失败且peer的NAT应答TCP RST包时,这种大量超时的危险副作用就显现出来了。由于终端机重复地尝试连接直到超时时间结束,这就导致P2PNAT方法产生SYN泛滥。诚然,这个问题在原本的P2PNAT方法中是不存在的,因为它不提倡端口预测。
 总的来说,我们发现,基于协议的TCP大部分情况下能够穿透NAT。应用程序必须通过端口预测来处理(解决)“delta”(“δ”)类型NAT,而且,当NAT上有足够的安全限制时,也必须使用带外信号来建立连接。延迟不敏感的应用程序,在放弃前,任何一方也都必须尝试连接两次(多次)。此外,应用软件不必依赖NAT保留空闲连接太久的时间,也不应该期望端到端的TCP序号一成不变。尽管,某些特定情况下,所有的TCP穿透NAT方法都不十分完美,但在当前的互联网中用于建立P2P的TCP连接中,第二种STUNT方法是最好的(鲁棒),它88%的情况都是成功的,而且不需要欺骗、RAW套接字或其它超级特权。它使用传统的TCP协议栈,传统的协议栈不支持TCP同时打开,然而,利用现代操作系统中的这种好处,它在许多通常情况下提供了100%的成功。最后,我们发现,它也是所有方法中实现最简单的,而且在Linux下和Windows下都能工作。我们鼓励应用软件开发者们,在他们现在还不能在NAT后的peer之间建立TCP的P2P应用软件中采用这种方法来提供TCP穿透NAT(功能)。

相关工作
从Dan Kegel在上世纪90年代后期第一次提出用于P2P游戏的UDP穿透NAT以来,NAT穿透长久以来一直是人们的梦想。他的基本方法被当作标准,并发表在参考文献[15]中。UDP(穿透NAT)方法在几个现行的文档和互联网草稿中已经有结果(也就是成熟的方法),这些文档和互联网草稿把NAT对UDP的行为进行了分类,并计划把它标准化。不显式控制NAT的TCP穿透NAT领域,才刚刚起步。本文已经分析了一些方法,也证明了这些方法在当前的互联网中穿透NAT(的可行性)。参考文献[6]中包括了类似的研究,作者测试了许多NAT对UDP和TCP穿透NAT特点的一小部分(子集)。我们提出了NAT行为和P2P的TCP建立(连接)的第一个全面研究,为在大范围商业NAT产品上的TCP穿透NAT技术提供了全面的集合(整理/汇总)。
像UPnP和MIDCOM这样的协议,为了便于P2P连接,他们允许终端应用软件显式的控制NAT。这种类型方法之所以呈下降趋势,是因为它们需要NAT中存在并支持这些协议。应用软件开发者们不能够依赖这些,因此,暂时这些方法不是最好的选择。
另一个处理TCP连接的方法是TURN[14],TURN方法中,TCP数据通过第三方代理(中转),因而,第三方代理具有潜在的网络瓶颈。通过在UDP上开通IPV6通道的方式,Teredo[14](方法)允许IPV6包穿透IPV4的NAT。这里,TCP原本就处在IPV6之上。Windows操作系统中已经实现了Teredo。
结论及将来的工作
本文第一次对NAT关于TCP方面对特点进行了全面的测评研究。尽管该研究表明TCP穿透当前NAT还有很多问题,不过它还是给了我很多值得高兴的(乐观的)。尽管存在NAT,而这些NAT当初设计时并未考虑过TCP穿透NAT,但我们还是能够看到,自然环境条件下TCP连接建立的成功率平均达88%,一些普通类型NAT的成功率高达100%。这些数字特别鼓励一个假设:很多年前可以普遍地假设TCP穿透NAT是不可能的。尽管对许多应用软件来说,11%的失败率是不可接受的,但这些应用软件的用户至少有选择,可以选择买一个支持TCP穿透的NAT设备,NAT提供商也有选择,可以选择把他们的NAT设备设计的对TCP更友好。
该研究在某些方面还是有限的(不全面不完整)。第一,我们没有测试所有现存的NAT设备。我们研究中大部分有效的NAT被限制在北美地区。第二,我测试的范围太小,也因此在准确预测广泛的成功率方面是存在偏差的。尽管可以使用市场数据协助,但这些数据在范围和详细程度上也是有限的。第三,我们只测试了家用NAT。企业网络中,“delta”(“δ”)型NAT的端口预测成功率通常更低一些,而这些对测评原本会更有帮助。第四,尽管TCP穿透NAT技术被广泛地用于(穿透)防火墙,但我们并没有测试NAT环境之外的防火墙。我们也没有测试IPV4到IPV6的转换网关。最后,与其他测评研究类似,这(研究)只是当前的现状。毫无疑问,在本项目进行过程中,同类NAT的新版本已经展现出与之前版本不同的行为。展望未来,我们希望,我们的TCP穿透NAT测试套件能够继续被用来拓宽我们对NAT和防火墙特性的认识,也能够继续跟得上NAT产品及其部署的趋势。

感谢
作者非常感谢Bryan Ford、Andrew Biggadile以及那些匿名的IMC评论家,因为他们为本文初稿反馈的珍贵的意见。我们也感谢Synergy Research Group,Inc.提供了及时的市场调查数据。最后,我们感谢许许多多的志愿者,他们在自己的系统上运行了STUNT测试client和P2P的TCP测试,并反馈了结果。
10 参考文献
[1] AUDET, F., AND JENNINGS, C. Internet draft: Nat behavioral requirements for unicast udp, July 2005. Work in progress.
[2] BASET, S. A., AND SCHULZRINNE, H. An Analysis of the Skype Peer-to-Peer Internet Telephony Protocol. Tech. Rep. CUCS-039-04, Columbia University, New York, NY, Sept. 2004.
[3] BIGGADIKE, A., FERULLO, D., WILSON, G., AND PERRIG, A.NATBLASTER: Establishing TCP connections between hosts behind NATs. In Proceedings of ACM SIGCOMM ASIA Workshop
(Beijing, China, Apr. 2005).
[4] BRADEN, R. RFC 1122: Requirements for Internet Hosts – Communication Layers, Oct. 1989.
[5] EPPINGER, J. L. TCP Connections for P2P Apps: A Software Approach to Solving the NAT Problem. Tech. Rep. CMU-ISRI-05-104, Carnegie Mellon University, Pittsburgh, PA, Jan. 2005.
[6] FORD, B., SRISURESH, P., AND KEGEL, D. Peer-to-peer communication across network address translators. In Proceedings of the 2005 USENIX Annual Technical Conference (Anaheim, CA, Apr. 2005).
[7] GUHA, S. STUNT - Simple Traversal of UDP Through NATs and TCP too. Work in progress. [online] http://nutss.gforge.cis.cornell.edu/pub/draft-guha-STUNT-00.txt.
[8] GUHA, S. STUNT Test Results. [online] http://nutss.gforge.cis.cornell.edu/stunt-results.php.
[9] GUHA, S., TAKEDA, Y., AND FRANCIS, P. NUTSS: A SIP-based Approach to UDP and TCP Network Connectivity. In Proceedings of SIGCOMM’04 Workshops (Portland, OR, Aug. 2004), pp. 43–48.
[10] HUITEMA, C. Internet draft: Teredo: Tunneling ipv6 over udp through nats, Apr. 2005. Work in progress.
[11] JENNINGS, C. Internet draft: Nat classification test results, Feb.2005. Work in progress.
[12] MICROSOFT CORPORATION. UPnP – Universal Plug and Play Internet Gateway Device v1.01, Nov. 2001.
[13] POSTEL, J. RFC 761: DoD standard Transmission Control Protocol,Jan. 1980.
[14] ROSENBERG, J., MAHY, R., AND HUITEMA, C. Internet draft:TURN – Traversal Using Relay NAT, Feb. 2004. Work in progress.
[15] ROSENBERG, J., WEINBERGER, J., HUITEMA, C., AND MAHY, R. RFC 3489: STUN – Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs), Mar. 2003.
[16] STIEMERLING, M., QUITTEK, J., AND TAYLOR, T. MIDCOM Protocol Semantics, June 2004. Work in progress.
[17] TAKEDA, Y. Internet draft: Symmetric NAT Traversal using STUN, June 2003. Work in progress.
[18] VANCE, A., Ed. Q1 2005 Worldwide WLAN Market Shares. Synergy Research Group, Inc., Scottsdale, AZ, May 2005, p. 40.

注释:
1处在NAT或防火墙后面的网络(Network behind a NAT or firewall)
2整篇文章中,NAT术语理解为包括防火墙(Throughout this paper, the term NAT is understood to include firewalls)
3有时指双层NAT(sometimes referred to as dual or double NAT)
4IP中存活时间字段(IP time-to-live field)
5最大段长(Maximum Segment Length)
6来回时间(Round-trip time)