如何实现P2P穿透.docx

上传人:b****8 文档编号:10870854 上传时间:2023-02-23 格式:DOCX 页数:15 大小:28.44KB
下载 相关 举报
如何实现P2P穿透.docx_第1页
第1页 / 共15页
如何实现P2P穿透.docx_第2页
第2页 / 共15页
如何实现P2P穿透.docx_第3页
第3页 / 共15页
如何实现P2P穿透.docx_第4页
第4页 / 共15页
如何实现P2P穿透.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

如何实现P2P穿透.docx

《如何实现P2P穿透.docx》由会员分享,可在线阅读,更多相关《如何实现P2P穿透.docx(15页珍藏版)》请在冰豆网上搜索。

如何实现P2P穿透.docx

如何实现P2P穿透

如何实现P2P穿透-1

 (2006-12-2910:

19:

38)

转载▼

分类:

 网络

iptables与stun

Stun协议(Rfc3489、详http:

//www.ietf.org/rfc/rfc3489.txt)将NAT粗略分为4种类型,即FullCone、RestrictedCone、PortRestrictedCone和Symmetric。

举个实际例子(例1)来说明这四种NAT的区别:

A机器在私网(192.168.0.4)

NAT服务器(210.21.12.140)

B机器在公网(210.15.27.166)

C机器在公网(210.15.27.140)

现在,A机器连接过B机器,假设是A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

8000)->B(210.15.27.166:

2000)。

同时A从来没有和C通信过。

则对于不同类型的NAT,有下列不同的结果:

FullConeNAT:

C发数据到210.21.12.140:

8000,NAT会将数据包送到A(192.168.0.4:

5000)。

因为NAT上已经有了192.168.0.4:

5000到210.21.12.140:

8000的映射。

RestrictedCone:

C无法和A通信,因为A从来没有和C通信过,NAT将拒绝C试图与A连接的动作。

但B可以通过210.21.12.140:

8000与A的192.168.0.4:

5000通信,且这里B可以使用任何端口与A通信。

如:

210.15.27.166:

2001->210.21.12.140:

8000,NAT会送到A的5000端口上。

PortRestrictedCone:

C无法与A通信,因为A从来没有和C通信过。

而B也只能用它的210.15.27.166:

2000与A的192.168.0.4:

5000通信,因为A也从来没有和B的其他端口通信过。

该类型NAT是端口受限的。

SymmetricNAT:

上面3种类型,统称为ConeNAT,有一个共同点:

只要是从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。

但是Symmetric有点不同,具体表现在:

只要是从同一个内部地址和端口出来,且到同一个外部目标地址和端口,则NAT也都将它转换成同一个外部地址和端口。

但如果从同一个内部地址和端口出来,是到另一个外部目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。

而且和PortRestrictedCone一样,只有曾经收到过内部地址发来包的外部地址,才能通过NAT映射后的地址向该内部地址发包。

现针对SymmetricNAT举例说明(例2):

A机器连接过B机器,假使是A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

8000)->B(210.15.27.166:

2000)

如果此时A机器(192.168.0.4:

5000)还想连接C机器(210.15.27.140:

2000),则NAT上产生一个新的映射,对应的转换可能为A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

8001)->C(210.15.27.140:

2000)。

此时,B只能用它的210.15.27.166:

2000通过NAT的210.21.12.140:

8000与A的192.168.0.4:

5000通信,C也只能用它的210.15.27.140:

2000通过NAT的210.21.12.140:

8001与A的192.168.0.4:

5000通信,而B或者C的其他端口则均不能和A的192.168.0.4:

5000通信。

通过上面的例子,我们清楚了Stun协议对NAT进行分类的依据。

那么,我们现在根据上述分类标准(或例子),来简要分析一下iptables的工作原理(仅指MASQUERADE、下同),看看他又是属于哪种NAT呢?

首先,我们去网上下载一个使用Stun协议检测NAT的工具,网址restrictedNATdetected。

我们先不要急着接受这个检测结果,还是先来分析一下iptables的工作原理吧!

iptables在转换地址时,遵循如下两个原则:

1、尽量不去修改源端口,也就是说,ip伪装后的源端口尽可能保持不变。

(即所谓的Preservesportnumber)

2、更为重要的是,ip伪装后只需保证伪装后的源地址/端口与目标地址/端口(即所谓的socket)唯一即可。

仍以前例说明如下(例3):

A机器连接过B机器,假使是A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

5000)->B(210.15.27.166:

2000)。

(注意,此处NAT遵循原则1、故转换后端口没有改变)

如果此时A机器(192.168.0.4:

5000)还想连接C机器(210.15.27.140:

2000),则NAT上产生一个新的映射,但对应的转换仍然有可能为A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

5000)->C(210.15.27.140:

2000)。

这是因为NAT(转换后210.21.12.140:

5000)->B(210.15.27.166:

2000)和NAT(转换后210.21.12.140:

5000)->C(210.15.27.140:

2000)这两个socket不重复。

因此,对于iptables来说,这既是允许的(第2条原则)、也是必然的(第1条原则)。

在该例中,表面上看起来iptables似乎不属于SymmetricNAT,因为它看起来不符合SymmetricNAT的要求:

如果从同一个内部地址和端口出来,是到另一个目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。

相反,倒是符合除SymmetricNAT外的三种ConeNAT的要求:

从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。

加上iptables具有端口受限的属性(这一点不容置疑,后面举反例证明之),所以好多检测工具就把iptables报告为PortrestrictedNAT类型了。

下面仍以前例接着分析(例4):

在前例中增加D机器在A同一私网(192.168.0.5)

A机器连接过B机器,假使是A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

5000)->B(210.15.27.166:

2000)

D机器连接过C机器,假使是D(192.168.0.5:

5000)->NAT(转换后210.21.12.140:

5000)->C(210.15.27.140:

2000)

由iptables转换原则可知,上述两个转换是允许且必然的。

如果此时A机器(192.168.0.4:

5000)还想连接C机器(210.15.27.140:

2000),则NAT上产生一个新的映射,但对应的转换则变为A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

5001)->C(210.15.27.140:

2000)。

这是因为,如果仍然将其转换为210.21.12.140:

5000的话,则其所构成的socket(210.21.12.140:

5000->210.15.27.140:

2000)将和D->C的socket一致,产生冲突,不符合iptables的第2条原则(注意,此处以5001表示转换后不同的端口,但事实上,iptables却并不按照内部端口+1的原则来产生新的端口)。

在本例中我们注意到,从同一个内部地址和端口A(192.168.0.4:

5000)出来,到不同的目标地址和端口,则NAT使用了不同的映射,转换成不同的端口。

上面这个例子在实际环境中比较少见,我们再以QQ为例举一个真实且常见的例子(例5)。

假设

A(192.168.0.4)和D(192.168.0.5)是同一NAT服务器(210.21.12.140)保护的两台私网机器,都运行了QQ客户端程序。

B机器在公网(210.15.27.166),运行QQ服务器程序。

C机器在公网(210.15.27.140),运行QQ客户端程序。

A上QQ先登陆到B,按照原则1,使用如下映射:

A(192.168.0.4:

4000)->NAT(转换后210.21.12.140:

4000)->B(210.15.27.166:

8000)(原则1,端口不变)

接着D上QQ也登陆到B,按照原则2,使用如下映射:

D(192.168.0.5:

4000)->NAT(转换后210.21.12.140:

4001)->B(210.15.27.166:

8000)(原则2,scoket不能有重复,此处4001仅表示转换后不同的端口,实际环境中决不是4001)

然后D欲和公网C(210.15.27.140)上的QQ通信,按照iptables转换原则,使用如下映射:

D(192.168.0.5:

4000)->NAT(转换后210.21.12.140:

4000)->C(210.15.27.140:

4000)

到此我们发现,和上例一样,从同一个内部地址和端口D(192.168.0.5:

4000)出来,到不同的目标地址和端口,则NAT使用了不同的映射,转换成不同的端口。

但和上例不一样的是,本例显然普遍存在于实际环境中。

上面所举两例表明,结论刚好和例3相反,即iptables应该属于SymmetricNAT。

为什么会出现彼此矛盾的情况呢?

首先从NAT分类的定义上来看,Stun协议和iptables对映射的理解不同。

Stun协议认为,一个映射的要素是:

内部地址端口和NAT转换后地址端口的组合。

而在iptables看来,一个映射的要素是:

NAT转换后地址端口和外部目标地址端口的组合。

另一方面则是Stun协议里DiscoveryProcess给出的测试环境不够全面之故,他只考虑了NAT后面仅有一台私网机器的特例(例3),没有考虑NAT后面可以有多台私网机器的普遍例子(例5)。

正是由于这两个原因,直接导致了上述矛盾的发生。

所以,凡按照Stun协议标准设计的NAT分类检测工具对iptables的检测结果必然是PortrestrictedNAT。

(事实上,在例3那样的特例下,iptables确实是一个标准的PortrestrictedNAT)

那么,iptables究竟属于哪种NAT呢?

我们再来回顾一下Stun协议对ConeNAT的要求:

所有(或只要是)从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。

虽然iptables在部分情况下满足“从同一个内部地址和端口出来的包,都将把他转换成同一个外部地址和端口”这一要求,但它不能在所有情况下满足这一要求。

所以理论上,我们就只能把iptables归为SymmetricNAT了。

下面,我们再来分析一下iptables的端口受限的属性,我们举一个反例证明之(例6),仍以前例说明如下:

A机器连接过B机器,假使是A(192.168.0.4:

5000)->NAT(转换后210.21.12.140:

5000)->B(210.15.27.166:

2000)

D机器连接过C机器,假使是D(192.168.0.5:

5000)->NAT(转换后210.21.12.140:

5000)->C(210.15.27.140:

2000)

现假设iptables不具有端口受限的属性,则另一E机器在公网(210.15.27.153:

2000)或C(210.15.27.140:

2001)向210.21.12.140:

5000发包的话,应该能够发到内部机器上。

但事实是,当这个包到达NAT(210.21.12.140:

5000)时,NAT将不知道把这个包发给A(192.168.0.4:

5000)还是D(192.168.0.5:

5000)。

显然,该包只能丢弃,至此,足以证明iptables具有端口受限的属性。

所以,iptables是货真价实的SymmetricNAT。

附:

1、Stun全称SimpleTraversalofUDPThroughNATs,所以本文所涉及的包,皆为UDP包。

2、本文虽然是针对linux下iptables的分析,但倘若把本文中关键词“iptables”换成“Win2000下的ics或nat”,则本文的分析过程完全适用于Win2000下的ics或nat。

即理论上Win2000下的ics或nat也是货真价实的SymmetricNAT,但实际上,凡按照Stun协议标准设计的NAT分类检测工具对其检测结果也必然是PortrestrictedNAT。

其实,不光是linux下iptables、或者Win2000下的ics或nat、再或者任何其他NAT产品,只要他们遵循和iptables一样的两条转换原则,那么他们在Stun协议下的表现是完全一样的。

3、虽然Win2000下的ics或nat在Stun协议下的表现和iptables完全一样,但其NAT时所遵循的原则1和iptables还是略有差别:

iptables对内部私网机器来的所有源端口都将适用Preservesportnumber,除非确因原则2发生冲突而不得不更换源端口号,但在更换端口号时并不遵循内部端口+1原则(似乎没有规律)。

Win2000下的ics或nat则仅对内部私网机器来的部分源端口(1025--3000)适用Preservesportnumber,对于那些超过3000的源端口号或者因原则2发生冲突的端口号,系统从1025开始重新按序分配端口,在此过程中,仍然遵循如前两个原则,只是原则1不再Preservesportnumber而已(在不与原则2发生冲突的前提下,尽量重复使用小的端口号,故使用1025的几率远远大于1026、1027…)。

即将推出其姊妹篇----iptables下udp穿越实用篇----“iptables与natcheck”

iptables与natcheck

Stun协议(Rfc3489、详http:

//www.ietf.org/rfc/rfc3489.txt)提出了4种NAT类型的定义及其分类,并给出了如何检测在用的NAT究竟属于哪种分类的标准。

但是,具体到P2P程序如何应用Stun协议及其分类法穿越NAT,则是仁者见仁、智者见智。

(因为Stun协议并没有给出也没有必要给出如何穿越NAT的标准)

在拙作“iptables与stun”一文中,笔者花大幅精力阐述了iptables理论上属于SymmetricNAT而非PortRestrictedCone。

对此,很多人(包括笔者最初学习Stun协议时)心中都有一个疑惑,即仅就Stun协议本身来说,PortRestrictedCone和SymmetricNAT的区别似乎不大,虽然两者的映射机制是有点不同,但他们都具有端口受限的属性。

初看起来,这两者在穿越NAT方面的特性也差不多,尤其是对于外部地址欲往NAT内部地址发包的情况。

既然如此,又为何有必要把iptables分得这么清呢,本文顺带解决了读者在这一方面的疑惑。

网http:

//midcom-

A机器在私网(192.168.0.4)

A侧NAT服务器(210.21.12.140)

B机器在另一个私网(192.168.0.5)

B侧NAT服务器(210.15.27.140)

C机器在公网(210.15.27.166)作为A和B之间的中介

A机器连接过C机器,假使是A(192.168.0.4:

5000)->A侧NAT(转换后210.21.12.140:

8000)->C(210.15.27.166:

2000)

B机器也连接过C机器,假使是B(192.168.0.5:

5000)->B侧NAT(转换后210.15.27.140:

8000)->C(210.15.27.166:

2000)

A机器连接过C机器后,A向C报告了自己的内部地址(192.168.0.4:

5000),此时C不仅知道了A的外部地址(C通过自己看到的210.21.12.140:

8000)、也知道了A的内部地址。

同理C也知道了B的外部地址(210.15.27.140:

8000)和内部地址(192.168.0.5:

5000)。

之后,C作为中介,把A的两个地址告诉了B,同时也把B的两个地址告诉了A。

假设A先知道了B的两个地址,则A从192.168.0.4:

5000处同时向B的两个地址192.168.0.5:

5000和210.15.27.140:

8000发包,由于A和B在两个不同的NAT后面,故从A(192.168.0.4:

5000)到B(192.168.0.5:

5000)的包肯定不通,现在看A(192.168.0.4:

5000)到B(210.15.27.140:

8000)的包,分如下两种情况:

1、B侧NAT属于FullConeNAT

则无论A侧NAT属于ConeNAT还是SymmetricNAT,包都能顺利到达B。

如果P2P程序设计得好,使得B主动到A的包也能借用A主动发起建立的通道的话,则即使A侧NAT属于SymmetricNAT,B发出的包也能顺利到达A。

结论1:

只要单侧NAT属于FullConeNAT,即可实现双向通信。

2、B侧NAT属于RestrictedCone或PortRestrictedCone

则包不能到达B。

再细分两种情况

(1)、A侧NAT属于RestrictedCone或PortRestrictedCone

虽然先前那个初始包不曾到达B,但该发包过程已经在A侧NAT上留下了足够的记录:

A(192.168.0.4:

5000)->(210.21.12.140:

8000)->B(210.15.27.140:

8000)。

如果在这个记录没有超时之前,B也重复和A一样的动作,即向A(210.21.12.140:

8000)发包,虽然A侧NAT属于RestrictedCone或PortRestrictedCone,但先前A侧NAT已经认为A已经向B(210.15.27.140:

8000)发过包,故B向A(210.21.12.140:

8000)发包能够顺利到达A。

同理,此后A到B的包,也能顺利到达。

结论2:

只要两侧NAT都不属于SymmetricNAT,也可双向通信。

换种说法,只要两侧NAT都属于ConeNAT,即可双向通信。

(2)、A侧NAT属于SymmetricNAT

因为A侧NAT属于SymmetricNAT,且最初A到C发包的过程在A侧NAT留下了如下记录:

A(192.168.0.4:

5000)->(210.21.12.140:

8000)->C(210.15.27.166:

2000),故A到B发包过程在A侧NAT上留下的记录为:

A(192.168.0.4:

5000)->(210.21.12.140:

8001)->B(210.15.27.140:

8000)(注意,转换后端口产生了变化)。

而B向A的发包,只能根据C给他的关于A的信息,发往A(210.21.12.140:

8000),因为A端口受限,故此路不通。

再来看B侧NAT,由于B也向A发过了包,且B侧NAT属于RestrictedCone或PortRestrictedCone,故在B侧NAT上留下的记录为:

B(192.168.0.5:

5000)->(210.15.27.140:

8000)->A(210.21.12.140:

8000),此后,如果A还继续向B发包的话(因为同一目标,故仍然使用前面的映射),如果B侧NAT属于RestrictedCone,则从A(210.21.12.140:

8001)来的包能够顺利到达B;如果B侧NAT属于PortRestrictedCone,则包永远无法到达B。

结论3:

一侧NAT属于SymmetricNAT,另一侧NAT属于RestrictedCone,也可双向通信。

显然,还可得出另一个不幸的结论4,两个都是SymmetricNAT或者一个是SymmetricNAT、另一个是PortRestrictedCone,则不能双向通信。

上面的例子虽然只是分析了最初发包是从A到B的情况,但是,鉴于两者的对称性,并且如果P2P程序设计得足够科学,则前面得出的几条结论都是没有方向性,双向都适用的。

通过上述分析,我们得知,在穿越NAT方面,SymmetricNAT和PortRestrictedCone是有本质区别的,尽管他们表面上看起来相似。

我们上面得出了四条结论,而natcheck网站则把他归结为一条:

只要两侧NAT都属于ConeNAT(含FullCone、RestrictedCone和PortRestrictedCone三者),即可双向通信。

而且natcheck网站还建议尽量使用PortRestrictedCone,以充分利用其端口受限的属性确保安全性。

目前,国内充分利用了上述思路的具有代表性的P2P软件是“E话通”()。

在对natcheck提供的思路进行详细分析后,开始探讨本文主题:

iptables与natcheck。

Natcheck脱胎于Stun协议,由拙作“iptables与stun”一文可知,其对iptables进行的穿越NAT兼容性测试结果必然是GOOD。

此外,我在该文中还提到一句,如果在每个NAT后面仅有一个客户端这种特殊情况下,iptables就是一个标准的PortrestrictedCone。

根据前面natcheck的结论,这样两个iptables后面的客户端应该可以互相穿越对方的NAT。

让我们来看一下实际情况(例2)呢?

仍然参考前例,只是两侧都使用iptables来进行地址转换。

(因为采用了iptables,故此处和前例稍有点区别,即转换后源端口不变)

A与B通过C交换对方地址的初始化环节此处略去,我们从A(192.168.0.4:

5000)向B(210.15.27.140:

5000)(注意因使用iptables而导致端口和前例不一样)发包开始分析,因为在本例中,两侧均只有一个客户端,我们姑且把iptables简化成PortrestrictedCone看待。

如前例一样,从A(192.168.0.4:

5000)到B(210.15.27.140:

5000)的第一个包必不能到达B,但其会在A侧iptables上留下记录,在这条记录没有超时之前(iptables下默认30秒),如果B也向A(210.21.12.140:

5000)发包,如前所述,按理该包应该能够到达A,但事实上却是永远到不了。

难道是natcheck的结论错了,或者是特殊情况下iptables并不是PortrestrictedCone(即仍然是SymmetricNAT),我们还是别忙着再下结论,先来看看来两侧iptables上留下的记录吧:

A侧:

cat/proc/net/ip_conntrack|grep192.168.0.4|grepudp

udp1718src=192.168.0.4dst=210

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1