TCP在P2P技术中如何实现NAT

原创 2006年05月20日 21:30:00

以下内容引用自:http://blogs.impx.net/dragonimp/
p2p:TCP穿透NAT防火墙
原文:Establishing TCP Connections Between Hosts Behind NATs
http://www.andrew.cmu.edu/user/ggw/natblaster.pdf

NATBLASTER:Establishing TCP Connections Between Hosts Behind NATs

 

Andrew Biggadike, Daniel Ferullo,

Geoff Wilson, Adrian Perrig Information Networking Institute,

Carnegie Mellon University

{biggadike, ferullo, ggw, perrig}@.cmu.edu

August 20, 2004

 

 

不同NAT后的主机间建立TCP连接
 

译(初稿):dragonimp@fzu 2005-6-14

 

摘要
防火墙和网络地址转换(NAT)设备正变得越来越流行了,同时他们也对使用点对点年协议建立连接造成一个非常大的问题。一些NAT设备抑制了来自外部网络到内部网络的TCP请求。这篇文章的目的是提出一个能够在两个NAT设备内部的主机间建立直接的TCP连接的方法,同时又尽量不依赖于第三方主机。我们已经在两个普通的硬件条件下实现了这个功能。我们能够为两个不同典型的NAT后面的主机建立TCP连接。一旦建立了这个连接,应用程序就可以跟原来的TCP一样调用这个连接,而不需要任何其他的帮助。

第一章        前言
NAT技术的出现从某种意义上解决了IPV4的32位地址不足的问题,它同时也对外隐藏了其内部网络的结构。NAT设备把内部网络跟外部网络隔离开来,并且可以让内部的主机可以使用一个独立的IP地址,并且可以为每个连接动态翻译这些地址。此外,但内部主机跟外部主机通信时,NAT设备必须为它分配一个唯一的端口号并连接到同样的地址和端口(目标主机)。NAT的另一个特性是它只允许从内部发起的连接的请求,它拒绝了所有不是由内部发起的来到外部的连接,因为它根本不知道要把这个连接转发给内部的哪台主机。

P2P网络已经日益流行。尽管p2p文件共享软件引发了很多争夺站,比如nepster 和 kazaa之间,但是还是有很多有用的并且合法的P2P软件存在着,比如即时消息共享和文件共享。另一个P2P程序是一个叫OpenHash的项目,它为公众提供了一个可用的分布式的哈希表,很多应用程序都在它的基础上开发了出来,比如很多的即时通信软件和可靠的CD标签库。

不幸的是,两个处于不同NAT后面的主机无法建立TCP连接因为各自的NAT都只允许外出的连接。NAT销售商在已经为NAT设备开发了端口映射的功能来解决这个问题。NAT管理员可以使用端口映射来为那些需要接受那些不是从内部发起的连接请求的主机指定端口。但是这种解决方法根据情况还需要很多其他的支持。当有的服务器需要动态的分配端口的时候,这种方法就很受限了。再说了,如果一般的用户没有权限或者不懂得如果进入NAT设备为他们指定端口映射,那这种方法就一点用处也没有了。

P2p协议对此已经阐述了记者通用的方法。第一个可被p2p协议使用技术是:那些本来不能当作服务器的程序收到了来自请求者的消息后主动向请求者发起连接。这种情况只适用于只有一方在NAT后面的情况。第二种通用的方法是通过两个主机都可以连接得到得代理路由数据,但是这种方法对于两个NAT后面的主机来说效率太低了,因为所有的数据都必须经过代理。其他相关的技术将在第三部分讨论。

我们努力的目标是找出一个可以让NAT后面的两个主机直接建立TCP连接的解决方案。特别地,我们已经开发出几种方案可以用于那些支持端口分配地NAT和那些支持LSR路由的网络。我们的方法是通过第三方提供建立直接连接需要的信息。根据不同的环境,我们开发了几种不同的方案可以在可以预测和适当的时间的情况下建立连接。这些技巧都需要把数据包的TTL值设置得很小,并且捕捉和分析外传得数据包以提供信息给第三方“媒人”。并且人为地向网络发送一些数据包用来检测NAT所分配地端口。补充一点,如果端口分配是随机地,我们就使用一种叫“birthday paradox”的方法减少检测的次数。这种方法需要的空间是直接的穷举所使用的空间的开方。

第二章        NAT的类型
NAT必须考虑路由器的三个重要的特性:透明的地址分配、透明路由、ICMP包负载解析。地址分配是指在一个网络会话开始的时候为内部不可以路由的地址建立一个到可路由地址的映射。NAT必须为原地址和目标地址都进行这样的地址分配。NAT的地址分配有静态的很动态的方式。静态的地址分配必须预先在NAT中定义好,就比如每个会话都指派一对<内部地址,外部端口>映射到某对<内部地址,内部端口>。相反地,动态的映射在每次会话的时候才定义的,它并不保证以后的每次会话都使用相同的映射。

一个相似的特性NAT必须实现的是透明路由。正如上面提到的,NAT是一种特殊的路由它在它所路由的数据包中翻译地址。这种转换基于数据流来改变相应的IP地址和端口。其次,这种转换必须是设备透明的,这样才保证对现有网络的兼容性。一个不是很明显的要求是,NAT必须保证内部网络的数据包不被发送到外部网络去。

最后一个NAT必须实现的特性是当收到ICMP错误包的时候,NAT使用正常的数据包做出同样的转换。当在网络中发生错误时,比如当TTL过期了,一般地,发送人会收到一个ICMP错误包。ICMP错误包还包含了尝试错误的数据包,这样发送者就可以断定是那个数据包发生了错误。如果这些错误是从NAT外部产生地,在数据包头部的地址将会被NAT分配的外部地址所代替,而不是内部地址。因此,NAT还是有必要跟对ICMP错误一样,对在ICMP错误包中包含的数据包进行一个反向的转换。

虽然所有的NAT都实现了这三个特性,但是根据他们的特点和他们所支持的网络环境,他们还可以进入分类。NAT可以分为四种:Two-way NATs,Twice NATs, Multi-homed NATs, 和 Traditional NATs。Two-way NATs,一般也叫双向NAT(Bidirectional NATs),在外部地址和内部地址间执行双向转换,尽管它个数据包只转换一个IP地址。这种NAT是唯一一种允许从外部发起的连接请求。相反地,Twice NATs,它每路由一个数据包都对内部和外部的地址进行转换。这种NAT用在那些外部地址和内部地址交叠的情况下。Multi-homed NATs对于Twice NATs来说,多了一个功能,它可以允许在内部使用不能路由的地址并且还可以有多个连接到外部网络。之所以Multi-homed NATs能够这样做,是因为它跟另一个保持通信以确定他们的地址映射是不变的。Multi-homed NATs允许大量的内部网络和增加冗余来允许多个连接到Internet。到目前为止,最常用的NAT是传统NAT(Traditional NATs),它可以分为基础NAT(Basic NATs)和NATP(Network Address Port Translation)两种。

基本NAT和NATP的区别它所能分配给内部地址的外部地址是否比内部地址多。一个Simple NAT用在那种所能分配的外部地址跟内部地址的数量相等或者更多的时候。这种NAT进行端口分配,因为每个内部地址都可以分配到一个唯一的外部地址。NATPS用于当NAT所能用来分配的外部地址的数量比内部地址少的时候,最常见的一种情况是很多的内部机器共享一个外部IP地址。在这种情况下,NAT必须分配端口来补充IP用以消除网络传输的不明确的几乎。NAT和NATP共同的地方就是他们都阻止外来的连接,并且都可以进行静态和动态的地址分配。

NAPT是传统NAT中最普遍的一种,因为它允许很多的内部连接共享很少量的外部网络地址。大部分为小型网络设计的商业NAT都是NAPT。我们选择NATP作为我们研究的对象就是因为它的流行和它通过不允许外来连接限制了P2P协议。后面我们就把NATPs简称为NATs了。

我们首先要做的是得到商业防火墙以确定他们的特性跟资料上记载的是否一样。我们使用NatCheck这个程序对三个常用的NAT设备进行了测试:Netgear MR814,Linksys BEFSR41, 和 Linksys BEFW11S4。三个NAT都有相似的行为:他们对UDP和TCP都进行了一致的转换,这表明在内部主机使用<内部IP:内部端口>的时候,NAT是否直接将<内部IP:内部端口>映射到<外部地址:外部端口>,而不管它连接出去的目标主机<目标IP:目标端口>是多少。一致转换是静态NAT与动态NAT截然不同的一个特点,因为这不只是跟内部主机使用的地址有关,而且还跟端口有关。RFC3002明确指出要支持一致转换。没有一个NAT支持环路转换,不管是TCP还是UDP,这表明NAT是否可以正确的处理两个只知道对方外部地址的内部主机之间的连接。在我们的项目中,我们假设两个主机是在不同的NAT后面的,所以这个测试跟我们的目标是无关的。最后,所有的NAT都提供了对非主动请求的外来TCP和UDP包都进行过滤,这个测试可以表明NAT是否预防非主动恳求的外来包进入到内部网络。非主动请求过滤发生在除了Two-way NAT之外的所有NAT中,这也是在不同NAT后面的主机建立P2P连接最主要的障碍了。
第三章        相关研究工作
为了解决NAT给很多协议带来的困难,一种MIDCOM的架构被提了出来。MIDCOM是一种可以允许NAT或者防火墙后面的用户根据需要改变NAT行为的而允许连接的一种协议。这个系统虽然在某些情况下是适用的,当它却不能保证每个时候都可以。在那些用户没有办法控制NAT的情况下,这种方法对于P2P的连接还是行不通的。很多时候NAT或者防火墙后面的用户通过代理服务器进行连接。一种商业的代理解决方法是Hopster提供的,Hopsetr的代理在连接方本地以隧道级别的传输在本地运行,它通过HTTPS连接到Hopster自己的机器。但是,因为Hopster的代理需要所有的传输都经过他们的机器,所有他们的方法跟我们的比起来就显得低效了,具体见第五章。

为了能够进行直接的P2P连接,出现了针对UDP的解决方法。UDP打洞技术允许在有限的范围内建立连接。STUN(The Simple Traversal of User Datagram Protocol through Network Address Translators)协议实现了一种打洞技术可以在有限的情况下允许对NAT行为进行自动检测然后建立UDP连接。在UDP打洞技术中,NAT分配的外部端口被发送给协助直接连接的第三方。在NAT后面的双方都向对方的外部端口发送一个UDP包,这样就在NAT上面创建了端口映射,双方就此可以建立连接。一旦连接建立,就可以进行直接的UDP通信了。在UDP打洞技术可以成功的情况下,我们在这篇文章中所用的有的技术也同样适用。建立TCP连接比UDP连接更有优势。首先,UDP连接不能够依赖建立好的连接,就是不能够持久连接。UDP是无连接的并且没有对明确的通信。一般地,NAT见了的端口映射如果一段时间不活动后就是过期。为了保持UDP端口映射,必须每隔一段时间就发送UDP包,就算没有数据的时候,只有这样才能保持UDP通信正常。第二,很多防火墙都配置成拒绝任何的外来UDP连接。最后,一个单纯的TCP连接的实现更直观,并且现有的代码简单得修改就可以使用我们的技术。

Walfish et al.指出,采用间接得服务可以提供NAT或者防火墙后面主机之间得连通性,通过在两主机向间接服务器打开一个连接,并且服务器在他们之间传输所有得通信,在这篇文章中我们会完成一个不需要这样得间接服务器也能建立起这样得连接。

相关文章推荐

C++:p2p通信,打洞技术,穿越NAT的实现

UDP/TCP穿越NAT的P2P通信方法研究(UDP/TCP打洞 Hole Punching) NAT设备的类型介绍:转载http://www.limou.net/?p=120 NAT设备的类...

P2P 之 UDP穿透NAT的原理与实现 (打洞技术)

首先先介绍一些基本概念:     NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就是为了能够地址重用。N...

[p2p]UDP用打洞技术穿透NAT的原理与实现

首先先介绍一些基本概念:             NAT(Network Address              Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下...

TCP实现P2P通信TCP穿越NAT

  • 2016年11月25日 10:02
  • 130KB
  • 下载

TCP实现P2P通信、TCP穿越NAT

  • 2013年12月13日 09:47
  • 94KB
  • 下载

【转载】 TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞

TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞作者:谢红伟下载源代码这个标题用了两个顿号三个名称,其实说得是同一个东西,只是网上有不同的说法罢了,另外好像还有人叫TCP打孔(我的朋友小妞听说...
  • wateryh
  • wateryh
  • 2011年07月06日 15:59
  • 189

TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞(转载)

TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞 作者:谢红伟 下载源代码 这个标题用了两个顿号三个名称,其实说得是同一个东西,只是网上有不同的说法罢了,另外好像还有人叫TCP打...
  • cuishi0
  • cuishi0
  • 2012年05月12日 17:30
  • 421
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:TCP在P2P技术中如何实现NAT
举报原因:
原因补充:

(最多只允许输入30个字)