Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3013692
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2010-08-15 09:58:10

P2P(Peer-to-Peer)通信的发展极其迅速,形成了很大的影响。和传统通信一样,P2P通信同样受到NAT/FW穿越问题的制约,因此解决好其相关的NAT/FW穿越问题非常重要。和传统通信相比,P2P通信中的NAT/FW穿越问题有很多独特的地方,目前已经发展出了多种不同的技术。本文首先描述P2P通信中NAT/FW穿越的一般性问题,随后介绍一些主要的技术,并且重点分析目前比较有代表性的直接通信穿越方法。同时也对NAT/FW类型和行为对于P2P穿越的影响进行了讨论。作为例子,描述了Skype和JXTA所采用的穿越机制。
关键词:P2P  NAT/FW穿越   Skype  JXTA
 

一、 引言

    P2P通信应用因为其很多优秀的特点吸引了Internet上众多的用户,发展非常迅速。除了Kazaa、BT、Napster、eDonkey/eMule、Gnutella等大家耳熟能详的文件和内容共享分发P2P应用外,近年来以Skype为代表的P2P多媒体通信应用日益走红。目前Skype在全球已经拥有3.67亿用户,而在中国其用户数量也十分惊人,已经达到1550万。以Skype为代表的这类 P2P通信,一般叫做“汇合”(Rendezvous)类P2P应用。本文下面的讨论主要针对“汇合”类P2P通信。

    目前的P2P通信主要应用在IP网络上,而IP网络一直存在公网和各种私网的划分。NAT/FW作为地址翻译和网络安全必要的设备位于公网和私网之间。常规的通信,比如VoIP和Videoconferencing/videotelephony都受到NAT/FW的制约。如果要在公网和私网或者多个不同的私网之间进行通信,必须进行NAT/FW的穿越。NAT/FW本身提供了地址翻译,使得IP数据流可以到达如果没有地址翻译不可路由的私网地址/公网地址,但是对于传送层和应用层协议会造成影响。所谓穿越就是克服这些影响使得通信可以正常进行。目前对于常规通信中的各种应用层协议比如H.323和SIP,以及传送层协议比如TCP和UDP等都发展出了相应的穿越技术。同样对于P2P通信,也必须解决NAT/FW穿越的问题。并且因为P2P通信的效率和优势本质上来源于任何一个Peer节点都可以和其它Peer节点建立连接这样一个事实,而Peer节点的数量极其巨大;同时P2P通信的应用层协议和传统通信不同而更加复杂,因此和传统的Client/Server通信相比,P2P通信的NAT/FW穿越问题更加复杂和困难。
    所幸的是,经过近年来的研究,人们已经发展出了多种适用于P2P通信的NAT/FW穿越技术。本文将介绍主要的技术。

二、 P2P通信中NAT/FW穿越的一般性问题

 

    首先我们应该明确一点,没有通用和万能的穿越方法,在一般通信中是这样,在P2P通信中更是如此。各种因素都会影响到某种具体的穿越技术的成败和效果,而在任何一种具体的网络场景和NAT/FW类型组合中,可能都需要联合使用多种穿越手段才能奏效。一个典型的例子就是Skype,其中集成了多种穿越策略和技术,分别在不同的情况下使用。为了理解这点,我们首先需要来讨论P2P通信的一些一般性问题。我们引入图1所示的典型网络场景。该场景几乎包含了各种可能的情况。对于图中元素简要说明如下:一般的“汇合”类P2P系统都有一个中央注册服务器(在Skype中叫做Login Server),所有的用户节点都需要首先向注册服务器进行注册,通过注册可以达到几个目的:第一是验证一个要求加入的用户节点的合法性;另外也使得这个新加入节点能够向Skype网络中其它节点以及自己的好友节点“广告”自己在线,以及发现当前在线的超级节点等。超级节点其实是从普通节点中选举出来的,必须具有公网IP地址并且其机器在物理属性上具有更大内存、更强的处理能力、以及足够的与网络连接的带宽。
我们考虑如下一般性问题:
1.通信双方节点和NAT/FW的几种关系
    假设通信的双方是P1和P2,概括起来有三种可能:
(1)P1和P2都位于公网上,则不需要考虑NAT/FW穿越;
(2)P1位于私网而P2位于公网,或者反过来;
(3)P1和P2位于各自的私网上;
    对于以上三种情况,NAT/FW的穿越策略和具体使用的技术是不同的。
2.多层NAT/FW的存在
    对于一个ISP来说,用户的企业网络或者家庭网络可以不直接接入公网,而是接入一个ISP自己的网络。这个ISP的网络相对于Internet来说,这个网络是一个“更大”的私网,而相对于连接到其上的企业网/家庭网络来说,又相当于一个公网。这样做的好处是可以保证更好的管理和安全性,同时也更加节约公共IP地址。但是对于NAT/FW穿越来说,则增加了更多的困难和问题的复杂性。
3.NAT/FW的类型对于穿越的影响
    NAT/FW的类型对于穿越策略和具体使用的技术是有影响的。对于NAT/FW的一种比较科学的分类基于其实现地址/端口翻译的方式。可以根据限制条件的严格程度分成:全锥型、受限锥型,端口受限锥型、对称型等四种。越是严格的NAT/FW,对于穿越的限制作用越大,目前最难穿越的是对称型NAT/FW。从是否记忆以前通信的全部状态来分,NAT/FW又可以分成无状态NAT/FW和有状态NAT/FW两种。有状态的NAT/FW对于在会话建立过程中需要多次握手的一些传送层或应用层协议的穿越会造成一定的困难。
4. 传送层的穿越和应用层的穿越
    传送层穿越主要是解决如何透过NAT/FW来建立TCP或者UDP连接,从而保证在P1和P2之间能够正确收发TCP或UPD数据报文。传送层穿越比较容易找到通用技术。传送层穿越只是为应用层穿越打开了通道。因为应用层的协议众多,每种协议的行为都不尽相同,因此穿越的情况非常复杂,也很难找到通用的方法,在P2P通信中尤其如此。因此对于应用层的穿越,一般都要使用所谓ALG(Application Layer Gateway)即应用层网关,对于不同的应用层协议ALG将提供不同的处理。当然,也还有一种办法可以把应用层穿越“变成”传送层穿越,那就是隧道技术——把应用层数据报文完全通过某种“隧道”比如UPD“隧道”穿过NAT/FW,使得NAT/FW“看不见”应用层报文。
三、 主要技术介绍
    目前已有的各种P2P通信穿越技术大致可以分成以下三类:
1.中继(Relaying)方法
    如果P1和P2分别位于各自的私网上,即位于各自的NAT/FW之后,那么,其通信流无法直接到达对方,需要有一个中继实体S来进行转发。即P1发给S,再由S转发给P2,反之亦然。S作为中继实体,可以是一个专用于此目的的穿越服务器,也可以是一个超级节点或者甚者普通节点,一般要求位于公网上,这样对于P1和P2来说,其地址是可达的。中继方法很常用,并且受到限制很少。但是其重大不足是中继实体需要很强的处理能力和很多的资源如内存和网络连接带宽等。当P2P网络中节点很多的时候,使用中继方法,Scalability就比较差。
2.连接反转(Connection Reversal)方法
    如果P1和P2中一个位于公网上,另外一个位于私网上,那么因为一般的NAT/FW都是所谓的“外向型”(outbound)的,即如果位于NAT/FW后的P1首先试图和位于公网的P2建立会话连接,NAT/FW允许其连接建立;但是反过来如果P2首先试图和P1建立连接就不被允许。那么当P2首先要和P1建立连接的时候,P2首先把请求发给一个穿越服务器S。S虽然位于公网上,但是在注册阶段,P1已经和S建立了连接,因此S可以把请求转发给P1,而P1收到请求后主动和P2建立连接,NAT/FW允许连接的建立,因此穿越成功。其缺点是应用局限性大,如果P1和P2都在各自私网上,则该方法无法奏效。
3.直接通信方法
    借助穿越服务器S的帮助直接在P1和P2间建立直接通信连接,P1和P2可以分别位于各自的私网上。两种常用的直接通信技术是:
(1)“凿洞”(Hole-punching)技术:在穿越服务器S的帮助下,P1和P2之间互相得到对方的私网地址/端口和经过NAT/FW翻译的公网地址/端口,然后利用这些信息直接建立通信连接。详细原理参见本文第四节。
(2)“隧道”技术:如果P1和P2之间已经(如通过“凿洞”)建立了UDP或者TCP连接,那么应用层协议报文和媒体流报文都可以通过传送层协议建立的一个“隧道”穿过NAT/FW,而NAT/FW“看不见”应用层协议和媒体流报文。 

四、 “凿洞”方法 

     本节介绍“凿洞”方法的基本原理和工作工程。”凿洞”方法在IETF RFC3027中进行了描述。为了简单起见,介绍UDP协议穿越的“凿洞”过程。TCP协议过程类似,但是稍微复杂一些,同时还可能受到TCP协议栈软件实现细节等一些因素的影响,因此就不在这里进行讨论了。图3给出了最复杂的一种情况,即P1和P2分别位于各自私网上,有各自的NAT/FW,并且存在ISP布署的NAT/FW,这是一个典型的多层NAT/FW情况。NA,NB分别表示P1和P2各自的NAT/FW,NC表示ISP的NAT/FW。在这种情况下,对于P1和P2来说,存在三组不同的IP地址和端口。参见表1。
 
表1 P1和P2的三组不同IP地址/端口
IP地址/端口节点P1,P2
P1
P2
私网地址/端口
10.0.0.1:4321
10.1.1.3:4321
ISP私网地址/端口
10.0.1.1:4500
10.0.1.2:5500
公网地址/端口
155.99.25.11:6200
155.99.25.11:6205
    其中ISP私网地址前面已经说过,对于企业网/家庭网来说,具有公网属性;而对于真正公网来说,又具有私网属性,因此是一种“半公网”地址。P1和P2的“半公网”地址/端口由各自的NAT/FW即NA和NB分配。而公网地址是由NC分配的。P1和P2在进行通信之前,已经(通过注册等方式)和穿越服务器S建立了连接。S通过这个连接,已经从来自P1和P2的IP报文中获得了各自的私网地址/端口,又从P1和P2的注册信息中获得了各自的公网地址/端口。如果P1要和P2建立连接,它无法知道P2的地址/端口信息,它把请求发给S,S收到该请求后,把该请求转发给P2,同时附加上P1的公网地址/端口和私网地址/端口;同时发给P1一个答复消息,附加上P2的公网地址/端口和私网地址/端口。在接到这两个消息后,P1和P2分别向对方的公网地址/端口发送UDP报文。对于NA来说,它把来自P1的报文的地址/端口转换成“半公网”地址/端口10.0.1.1:4500。报文到达NC,这个时候,NC识别出目的公网地址155.99.25.11是一个它自己曾经分配过的公网地址,因此判断这个目的公网地址所对应的节点在自己管辖的私网上。同时NC根据目的端口6205可以判断出目的节点其实在NB管辖的私网上。于是NC就不把来自P1的报文发送到公网上,而是“环回”(loopback)到私网上,同时进行了地址和端口的替换,把报文的源地址/端口替换成155.99.25.11:6200,目的地址/端口替换成P2的“半公网”地址/端口10.0.1.2:5500。那么NB收到报文后,就可以根据目的地址/端口把报文发给P2。同样道理,来自P2的报文通过类似的过程,也最终通过NC和NA到达了P1。这里必须要求NC支持这种识别目的地址/端口位于自己管辖私网上并对报文进行“环回”的能力,这在NAT/FW的技术术语上叫做“法卡”(Hairpin)。随着“凿洞”技术的普及使用,市场上支持“法卡”特性的NAT/FW产品日益增多。
    “凿洞”的思想体现在:当来自P1的第一个报文首先到达NA时,NA记录下了目的地址/端口155.99.25.11:6205。那么当来自NC“环回”的P2报文到达NA后,NA发现其源地址/端口是155.99.25.11:6205已经记录,因此允许通过,相当于P1的第一个报文首先在NA上开凿了一个洞口,让来自P2的报文通过。同样道理来自P2的报文首先在NB上“凿洞”允许来自P1的报文通过。如果P1和P2在收到S的消息后同时开始向对方发送报文,那么并没有保证报文到达对方NAT/FW时候,洞口已经存在。如果洞口还没有开凿报文会被丢弃,需要多次尝试。另外也可以采用有先后顺序的“凿洞”方法(Sequential hole-punching),该方法特别对于TCP协议的“凿洞”适用。UDP会话存在一定时间后如果没有报文通过会被NAT/FW终结,这个“一定时间”是由NAT/FW的定时器决定的,并不存在标准数值。因此P2P应用程序需要周期性地向NAT/FW发送keep-alive报文以保持UDP“洞口”的存活。
 
    需要说明的是,虽然从名字上听,“凿洞”很容易使人联想到安全威胁,但其实“凿洞”方法是安全的。因此基于“凿洞”来进行NAT/FW穿越的P2P通信是安全的。因为“凿洞”方法允许P2P应用程序在绝大多数NAT/FW的缺省安全策略允许范围内正常工作,在P2P数据报文传送的路径上,通过正当的方式向各个NAT/FW指示出该会话是被“邀请”的,因此是可以被接受的。显然,“凿洞”完全采用安全策略内允许的做法,而不象有些NAT/FW穿越技术那样需要通过伪造报文等带有一定安全风险的手段来实现。基于“凿洞”的直接通信NAT/FW穿越方法在运营商对于P2P通信的监管和控制方面有技术优势,因此是容易被运营商所接受的。
五、 Skype的NAT/FW穿越机制介绍
Skype穿越各种NAT/FW的能力得到了实践的充分检验和业界的赞誉。同时因为其技术属于私有,外界无法深入了解细节。但是在过去几年中,有学术研究机构通过试验的方法,把Skype当成“黑盒子”进行研究,从而对于其NAT/FW穿越行为有了一定的认识,很多技术爱好者也在博客上进行讨论。而最近在Skype公司的技术白皮书中,提供了一些原理性的描述,结果和外界的分析比较接近。本节结合这些材料简要介绍其穿越机制的原理。
 
Skype其实使用了多种NAT/FW穿越技术。分析如下:
 
(1) 私有变种STUN协议探测NAT/FW的行为。Skype的卓越穿越能力首先来自“知己知彼”,为此需要对于NAT/FW的类型和行为进行准确的探测和预测。IETF的STUN协议是一种可用于探测的很好的工具。Skype的探测机制和STUN非常相似,但是功能可能更强、性能可能更好。因此是STUN的一个私有变种。
(2)中继技术。前面已经说过,如果中继的实体是一个或者少数中心服务器,其Scalability就非常差。Sky解决了这个问题。Skype的重要特色是使用了一种带有超级节点的P2P架构。超级节点或者其它位于公网上的节点都可以担当中继实体的角色。但是,Skype也不轻易使用中继,可能只有在“凿洞”技术无法奏效的情况下才使用中继技术。
(3) 连接反转技术。如果进行通信的两方节点有一方在公网上,就可以进行连接反转。具体原理参见第3节。
(4)“凿洞”直接通信技术。对于通信双方节点都位于各自私网上的情况,Skype首先考虑采用“凿洞”的方法,试图建立直接通信。如果“凿洞”不成功,则可能采用中继技术。
从人们的研究结果看,超级节点所占用的带宽比普通节点平均多不到5%,因此中继应该是不经常使用的,也就是说其“凿洞”技术可以解决大多数的穿越问题。
 
    当然目前在没有Skype正式公开其技术的情况下,人们只能通过这类非直接研究手段试图了解其内部工作机理。也许真相要一直等到Skype对其技术进行解密的那一天才能完全大白于天下。

六、 JXTA的NAT/FW穿越机制介绍

    JXTA(JuXTApose一词的缩写,表示对等、并置的意思)是一套开放协议规范,使得任何支持该规范的设备可以进行P2P通信。因此其实JXTA为开发P2P应用提供了一个和具体编程语言无关(C/C++和JAVA)基础平台,而实际上JXTA目前也已经成为很多P2P应用开发的有效平台。JXTA支持NAT/FW穿越机制。图4给出了一个示例,应用程序用CORBA组件来实现,底层的 JXTA支持NAT/FW穿越,使得上层的应用程序可以透明地实现跨多个安全域的自由通信。
 
    在基于JXTA的P2P网络中,“汇合”节点可以和多达数千个普通节点连接,而每个“汇合”节点知道其它“汇合”节点的位置。所有的“汇合”节点形成一个层次体系,使得scalability得到保证。JXTA使用中继机制来实现穿越,其原理如图5所示。而提供穿越功能的是中继节点,一般要求中继节点位于公网上。中继节点在NAT/FW上某个打开的端口上持续监听向外的连接。对于位于NAT/FW后面的节点,需要知道至少一个中继节点。为了和JXTA网络上的另外一个节点通信,该节点向中继节点发送请求。中继节点将该请求向目的节点发送,目的节点将响应消息发送给中继节点。而通信发起节点周期性向中继节点查询是否有来自目的节点的响应消息,如果有响应消息,则将消息从消息队列中取出处理。

七、 NAT/FW类型和行为对于穿越的影响

    本节描述NAT/FW的类型和行为对于P2P通信NAT/FW穿越的影响,同时提出对于NAT/FW的要求。满足这样要求的NAT/FW叫做“P2P友好”的NAT/FW。当前市场上越来越多的NAT/FW已经具备了“P2P友好”特性。对于“P2P友好”特性,IETF的BEHAVE工作组进行了深入的研究。下面从几个方面刻画“P2P友好”特性。
 1.地址/端口翻译的一致性
    对于“凿洞”方法,一个前提是NAT/FW地址/端口的翻译应该是一致的。这种一致性就是始终把私网上的同一个地址/端口翻译成同一个公网地址/端口或“半公网”地址/端口,具有这种性质的NAT/FW就是锥型NAT/FW。在第四节的例子中,如果P1和穿越服务器S第一次通信(注册)时,其私网地址/端口是10.0.01:4321,NA将它翻译成10.0.1.1:4500,而后又被NC翻译成155.99.25.11:6200。S认为这就是P1的公网地址,把它告诉P2。P2是按照这个地址/端口来向P1发送UDP报文的。P1在向P2发送的第一个报文时,如果NA的翻译不一致,在NA上为10.0.01:4321翻译出另外一个结果,那么这个开凿的洞口对于从P2来的报文是不通的。所以为了支持“凿洞”,NAT必须是锥型的。而如果是更加严格的对称型,前后两次翻译的结果肯定不相同,因此“凿洞”无法成功。为了对付对称型NAT/FW,“凿洞”技术出现了进化变种,只要NAT/FW翻译地址/端口的方式具有可预测性,在多数情况下也可以穿越成功。预测的前提是探测NAT/FW的行为,可以用STUN等协议实现。但是预测NAT/FW行为如果出现偏差,则会导致不可预测的结果,因此这种做法有相当的风险。
2.具有正确处理“非被邀请”TCP连接的能力
    对于TCP“凿洞”来说,可能NAT/FW会收到一个看上去是“非被邀请”(unsolicited)的来自公网的SYN报文。在这种情况下正确的处理方法是悄悄地丢弃这个报文。但是一些“不友好”的NAT/FW主动通过发送TCP RST报文甚至ICMP错误报告消息来拒绝该报文,则会使TCP“凿洞”受到干扰甚至失败。
 
3.对于净荷中的IP地址信息不进行干扰和处理.
    “P2P友好”的NAT/FW不应该对于净荷中的IP地址信息进行干扰和处理,而只是处理报文头部的IP地址信息。这点很重要。不幸的是,现在很多NAT/FW进行这样自作聪明的处理。这类NAT/FW扫描净荷中的数据,识别那些看起来像IP地址的4字节信息并进行处理,从而干扰了穿越行为。当然对于P2P应用程序来说,可以通过把净荷中的IP地址信息进行变换处理的办法,来使得NAT/FW在扫描净荷内容时候不能识别出这些IP地址信息。
4.“法卡”特性
    前文我们已经分析指出,NAT/FW应该支持“法卡”特性,正确地把来自其自身管辖私网的报文“环回”到私网上,而不是发送到公网上去。

八、 结束语

    P2P通信的发展日益蓬勃,方兴未艾。为了推动P2P通信的发展,NAT/FW穿越问题是必须很好加以研究并解决的问题。因为虽然IPv4地址不足是NAT出现的根本原因之一,但是即使过渡到了IPv6时代,至少在初期当IPv4和IPv6并存时,对于NAT/FW的需求反而会增大。另外NAT/FW所带来的私网节点的匿名性和不可访问性等安全好处也是其继续存在的理由。所以P2P通信中的NAT/FW穿越问题将会在相当长时期内存在,应该引起该领域研究者的充分重视。我们相信,P2P通信的技术进步和市场需求将催生更多、更有效的NAT/FW穿越技术,而后者反过来也将推动P2P通信更加快速地前进。
阅读(1194) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~