本文共 3298 字,大约阅读时间需要 10 分钟。
NAT
是为了节省IP
地址而设计的,但它隐藏了内网机器的地址,“意外”起到了安全的作用。对外不可见,不透明的内部网络也与互联网的“公平”应用,“相互共享”的思想所不容,尤其是P2P
网络中“相互服务”的宗旨,所以穿越NAT
,让众多内部网络的机器也参与到P2P
网络中的大集体中来,一直是P2P
开发者的所希望的。穿越NAT
需要借助外部的支持,说白了就是“内外勾结”,骗过NAT
。很多P2P
网络成功地实现了这一目标,但还是有一些“遗憾”---
并非所有的情况下都可以。由于客户端是主动登录P2P
网络才可穿越,所以P2P
的方式也没有违背企业的内部管理原则,毕竟“自由世界”的加入都是自觉自愿的。 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
网络的基础有了问题,具体的表现为: n 内网主机IP
是私有的,外部主机看不到,也无法主动发起连接 n 即使知道了内网IP
,但NAT
会丢弃没有在影射表的数据包 n 内网主机可以作为客户端访问外网,但不能作为服务器提供服务 n 当两个主机都位于各自的NAT
之后,要实现P2P
的连接,就不仅是谁主动的问题,而是如何解决在两个NAT
上同时有对方映射表项的问题。 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
。 位于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
无法获取这个端口,所以不适用本方法。 Ø 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
上打洞 本文转自 zhaisj 51CTO博客,原文链接:http://blog.51cto.com/zhaisj/58651,如需转载请自行联系原作者