搜档网
当前位置:搜档网 › P2P网络“自由”穿越NAT的“秘密”

P2P网络“自由”穿越NAT的“秘密”

P2P网络“自由”穿越NAT的“秘密”
P2P网络“自由”穿越NAT的“秘密”

穿越NAT的意义:

NAT是为了节省IP地址而设计的,但它隐藏了内网机器的地址,“意外”起到了安全的作用。对外不可见,不透明的内部网络也与互联网的“公平”应用,“相互共享”的思想所不容,尤其是P2P网络中“相互服务”的宗旨,所以穿越NAT,让众多内部网络的机器也参与到P2P 网络中的大集体中来,一直是P2P开发者的所希望的。穿越NAT需要借助外部的支持,说白了就是“内外勾结”,骗过NAT。很多P2P网络成功地实现了这一目标,但还是有一些“遗憾”---并非所有的情况下都可以。由于客户端是主动登录P2P网络才可穿越,所以P2P的方式也没有违背企业的内部管理原则,毕竟“自由世界”的加入都是自觉自愿的。

NAT原理:

NAT(Network Address Translation)网络地址转换/网络地址翻译。

工作原理:NAT主要的通过对数据包头的地址替换来完成内网计算机访问外网服务的。当内部机器要访问外部网络时,NAT设备把内部的IP1与端口号1(网络层地址与传输层地址),转换成NAT的外部IP2与新的端口号2,再送给外部网络,数据返回时,再把目的为IP2:端口2的数据包替换为IP1:端口1,送给内网机器。若通讯协议的内容中有IP地址的传递,如FTP协议,NAT在翻译时还要注意数据包内涉及协议地址交互的地方也要替换,否则协议就会出现地址混乱。在NAT设备中维护了这个要替换地址的映射表,并根据内部计算机的通讯需求维护该表。外部网络来数据包能否进入NAT,主要是看是否已经有可映射的表项,若没有就会丢弃。

NAT的外部公网地址可以是一个IP,也可以是一个网段,形成地址池。NAT还可以把某个外网地址直接影射给内网的某个服务器,让外网的用户可以直接访问到这台服务器。NAT的工作的隐藏内网的机器,但允许内网主动打开到外网的通讯“通道”,也就是建立映射表项。

NAT给P2P带来的问题是:NAT只允许单方面发起连接,通讯的双方不是平等的,P2P 网络的基础有了问题,具体的表现为:

内网主机IP是私有的,外部主机看不到,也无法主动发起连接

即使知道了内网IP,但NAT会丢弃没有在影射表的数据包

内网主机可以作为客户端访问外网,但不能作为服务器提供服务

当两个主机都位于各自的NAT之后,要实现P2P的连接,就不仅是谁主动的问题,而是如何解决在两个NAT上同时有对方映射表项的问题。

STUN协议(IETF RFC 3489):

STUN协议是一种通道协议,可以作为正式通讯前的通路建立,它采用的是用户终端干预的一种方法,可以解决应用协议内部传递IP地址给NAT带来的麻烦。用户通过其他方法得到其地址对应在NAT出口上的对外地址,然后在报文负载中所描述的地址信息就直接填写NAT上对外地址,而不是内网的私有IP,这样报文的内容在经过NAT时就按普通的NAT 流程转换报文头部的IP地址即可,负载内的IP地址信息无需再修改。利用STUN的思路可以穿越NAT。STUN协议是客户端/服务器协议,分两种请求方式:一是UDP发送的绑定请求(Binding Requests),二是TCP发送的秘密请求(Shared Secret Requests)。绑定请求用于确定NAT分配的绑定地址。

STUN标准中,根据内部终端的地址(P:p)到NAT出口的公网地址(A:b)的影射方式,把NAT分为四种类型:

1. Full Cone:来自相同的内部地址的请求消息映射为相同的外部地址,与外部地址(目的地址)无关。映射关系为P:p?A:b,任何外部主机可通过(A:b)发送到数据到(P:p)上。

2. Restricted Cone:来自相同的内部地址的请求消息映射为相同的外部地址,返回的数据只接受该内部节点曾发数据的那个目的计算机地址X。映射关系为P:p?A:b?X,只有来自X的数据包才可通过(A:b)发送到数据到(P:p)上。

3. Port Restricted Cone:来自相同的内部地址的请求消息映射为相同的外部地址,返回的数据只接受该内部节点曾发数据的那个目的地址X:x。映射关系为P:p?A:b?X:x,只有来自X:x的数据包才可通过(A:b)发送到数据到(P:p)上。

4. Symmetric(对称) NAT:只有来自相同的内部地址(P:p),并且发送到同一个地址(X:x) 的请求消息,才被映射为相同的外部地址(A:b),返回的数据只接受该内部节点曾发数据的那个目的地址X:x。映射关系为P:p?A:b?X:x,当(P:p)访问(Y:y)时,映射为P:p?B:c?Y:y。

P2P利用STUN穿越NAT:

位于NAT后面终端A与B要穿越NAT直接通讯,可以借助在公网上的第三者Server 来帮助。

穿越NAT的情况分为为两种方式:1、一方在NAT之后,一方在公网上。这种情况相对简单,只要让NAT之后的终端先发起通讯,NAT就没有作用了,它可以从Server上取得另一个Peer的地址,主动连接,回来的数据包就可以方便地穿越NAT。2、双方都在NAT

之后,连接的成功与否与两个NAT的类型有关。主要的思路的先通过终端与Server的连接,获得两个终端在NAT外部的地址(IP与端口号),再由终端向对方的外部地址发邀请包,获取自己与对方通讯的外部地址,俗称为“打洞”。关键是获取了NAT外部映射的地址,就可以发包直接沟通,建立连接。但当一方是对称型,另一方是Port Restricted或对称型时,无法有效获取外部地址,邀请包无法到达对方,也就无法穿越NAT。具体的分析可以根据两个NAT的类型分成若干情况分析,这里给一般的穿越例子。

实例:UDP穿越NAT:

A登录Server,NAT A分配端口11000,Server得到A的地址为100.10.10.10:11000 B登录Server,NAT B分配端口22000,Server得到B的地址为200.20.20.20:22000 此时B会把直接来自A的包丢弃,所以要在NAT B上打一个方向为A的洞,那么A就可以向200.20.20.20:22000发送数据了

打洞的指令来自Server。B向A的地址100.10.10.10:11000发一个UDP报文,被NAT A 丢弃,但在NAT B上建立映射记录,NAT B不在丢弃来自A的报文。

Server通知A可以通讯,A发起数据UDP包给B,NAT B放行,B收到A的包,双方开始通讯

注:若是对称NAT,当B向A打洞的端口要重新分配(NAT A不会再分配11000端口),B无法获取这个端口,所以不适用本方法。

实例:TCP穿越NAT:

A登录Server,NAT A分配端口11000,Server得到A的地址为100.10.10.10:11000 B登录Server,NAT B分配端口22000,Server得到B的地址为200.20.20.20:22000 A向B发送TCP数据包SYN:192.168.10.11:1234=>200.20.20.20:22000,在NAT A 上打洞

B向A发送TCP数据包SYN:192.168.20.22:1234=>100.10.10.10:11000,在NAT B 上打洞

通道建立,A与B三次握手建立TCP连接

对穿越NAT 做些总结:

先做个约定:

内网A 中有:A1(192.168.0.8)、A2(192.168.0.9)两用户,

网关X1(一个NAT 设备)有公网IP 1.2.3.4

内网B 中有:B1(192.168.1.8)、B2(192.168.1.9)两用户,

网关Y1(一个NAT 设备)有公网IP 1.2.3.5

公网服务器:C (6.7.8.9) D (6.7.8.10)

NAT 两大类:

● NAT(Network Address Translators):称为基本的NAT

其核心是替换IP 地址而不是端口,这会导致192.168.0.8使用4000端口后,192.168.0.9如何处理?

具体参考RFC 1631

基本上这种类型的NAT 设备已经很少了。或许根本我们就没机会见到。 ● NAPT(Network Address/Port Translators)

其实这种才是我们常说的NAT

NAPT 的特点是在网关时,会使用网关的 IP ,但端口会选择一个和临时会话对

在网关时

1.2.3.4:4000——6.7.8.9:8000 服务器C

6.7.8.9:8000

应的临时端口。

如下图:

网关上建立保持了一个1.2.3.4:62000的会话,用于192.168.0.8:4000与6.7.8.9:8000之间的通讯。

对于NAPT ,又分了两个大的类型:

差别在于,当两个内网用户同时与6.7.8.9:8000的处理方式不同:

1、Symmetric NAT 型(对称型)

在网关时

1.2.3.4:62000——6.7.8.9:8000 服务器C

6.7.8.9:8000

这种形式会让很多p2p 软件失灵。

2、ConeNAT 型(圆锥型)

目前绝大多数属于这种。Cone NAT 又分了3种类型:

a) Full Cone NAT (完全圆锥型):从同一私网地址端口192.168.0.8:4000发

至公网的所有请求都映射成同一个公网地址端口1.2.3.4:62000,192.168.0.8可以收到任意外部主机发到1.2.3.4:62000的数据报。

b) AddressRestricted Cone NAT (地址限制圆锥型):从同一私网地址端

口192.168.0.8:4000发至公网的所有请求都映射成同一个公网地址端口

1.2.3.4:62000,只有当内部主机192.168.0.8先给服务器C 6.7.8.9发送一个数

在网关时,两个不同session 但端口号不同

1.2.3.4:62000——6.7.8.9:8000 1.2.3.4:62001——6.7服务器C 6.7.8.9:8000 服务器D

6.7.8.10:8000

在网关时,两个不同session 但端口号相同

1.2.3.4:62000——6.7.8.9:8000 1.2.3.4:62000——6.7服务器C 6.7.8.9:8000 服务器D

6.7.8.10:8000

据报后,192.168.0.8才能收到6.7.8.9发送到1.2.3.4:62000的数据报。

c) Port Restricted Cone NAT (端口限制圆锥型):从同一私网地址端口

192.168.0.8:4000发至公网的所有请求都映射成同一个公网地址端口

1.2.3.4:62000,只有当内部主机192.168.0.8先向外部主机地址端口6.7.8.9:8000发送一个数据报后,192.168.0.8才能收到6.7.8.9:8000发送到

1.2.3.4:62000的数据报。

请注意上述描叙中的区别!

穿越NAT 的实现:

两内网用户要实现通过各自网关的直接呼叫,需要以下过程:

1、 客户机A1、B1顺利通过格子网关访问服务器C ,均没有问题(类似于登录)

2、 服务器C 保存了A1、B1各自在其网关的信息(1.2.3.4:62000、1.2.3.5:31000)没有问题。并可将该信息告知A1、B2。

3、 此时A1发送给B1网关的1.2.3.5:31000是否会被B1收到?答案是基本上不行(除非Y1设置为完全圆锥型,但这种设置非常少),因为Y1上检测到其存活的会话中没有一个的目的IP 或端口于1.2.3.4:62000有关而将数据包全部丢弃!

4、 此时要实现A1、B1通过X1、Y1来互访,需要服务器C 告诉它们各自在自己的网关上建立 “UDP 隧道”,即命令A1发送一个

192.168.0.8:4000——1.2.3.5:31000的数据报,B1发送一个

X1在网关时 1.2.3.4:62000——6.7.8.9:80服务器C

6.7.8.9:8000

B1在客户机时 192.168.1.8:4000——6.7.8.9:8000

Y1在网关时

1.2.3.5:31000——6.7.8.9:80

192.168.1.8:4000——1.2.3.4:62000的数据报,UDP形式,这样X1、Y1上均存

在了IP端口相同的两个不同会话(很显然,这要求网关为Cone NAT型,否则,对称型Symmetric NAT设置网关将导致对不同会话开启了不同端

口,而该端口无法为服务器和对方所知,也就没有意义)。

5、此时A1发给Y1,或者B1发给X1的数据报将不会被丢弃且正确的被对

方收到

综合P2P可实现的条件需要:

1、中间服务器保存信息、并能发出建立UDP隧道的命令

2、网关均要求为Cone NAT类型。Symmetric NAT不适合。

3、完全圆锥型网关可以无需建立udp隧道,但这种情况非常少,要求双方

均为这种类型网关的更少。

4、假如X1网关为Symmetric NAT,Y1为Address Restricted Cone NAT或Full

Cone NAT型网关,各自建立隧道后,A1可通过X1发送数据报给Y1到

B1(因为Y1最多只进行IP级别的甄别),但B2发送给X1的将会被丢弃(因

为发送来的数据报中端口与X1上存在会话的端口不一致,虽然IP地址

一致),所以同样没有什么意义。

5、假如双方均为Symmetric NAT的情形,新开了端口,对方可以在不知道

的情况下尝试猜解,也可以达到目的,但这种情形成功率很低,且带来

额外的系统开支,不是个好的解决办法。

6、不同网关型设置的差异在于,对内会采用替换IP的方式、使用不同端口

不同会话的方式,使用相同端口不同会话的方式;对外会采用什么都不

限制、限制IP地址、限制IP地址及端口。

7、这里还没有考虑同一内网不同用户同时访问同一服务器的情形,如果此

时网关采用Address Restricted Cone NAT或Full Cone NAT型,有可能导

致不同用户客户端可收到别人的数据包,这显然是不合适的。

一些现在常用的技术:

ALG(应用层网关):它可以是一个设备或插件,用于支持SIP协议,主要类似与在网关上专门开辟一个通道,用于建立内网与外网的连接,也就是说,这是一种定制的网关。更多只适用于使用他们的应用群体内部之间。

UpnP:它是让网关设备在进行工作时寻找一个全球共享的可路由IP来作为通道,这样避免端口造成的影响。要求设备支持且开启upnp功能,但大部分时候,这些功能处于安全考虑,是被关闭的。即时开启,实际应用效果还没经过测试。

STUN(Simple Traversalof UDP Through Network):这种方式即是类似于我们上面举例中服务器C的处理方式。也是目前普遍采用的方式。但具体实现要比我们描述的复杂许多,光是做网关Nat类型判断就由许多工作,RFC3489中详细描述了。

TURN(Traveral Using Relay NAT):该方式是将所有的数据交换都经由服务器来完成,这样NAT将没有障碍,但服务器的负载、丢包、延迟性就是很大的问题。目前很多游戏均采用该方式避开NAT的问题。这种方式不叫p2p。

ICE(Interactive Connectivity Establishment):是对上述各种技术的综合,但明显带来了复杂性。

总之,NAT的存在代表着一种时尚,那就是——不求简单,但求复杂,坚决把你搞晕,反正没我责任。

相关主题