检查你的NAT (Network Address Translator) 和p2p协议的兼容性

原文: http://midcom-p2p.sourceforge.net/

NAT Check
Version 3, with TCP Support!
检查你的NAT (Network Address Translator) 和p2p协议的兼容性
NAT Check by Bryan Ford, web magic by Dave Andersen
Hosted by the MIDCOM-P2P project on SourceForge

P2P协议的实现在当前IPV4环境下,就技术上来讲,更重要的是如何穿越NAT以及保证连接的稳定性能。有必要先澄清几个概念。
Firewall, NAT, Loopback tanslation (参考 http://blog.csdn.net/hxhbluestar/archive/2004/11/11/177793.aspx)

NAT Check是这样的一个小程序,它可以自动检测你的NAT对P2P协议的支持程度,version 3版本可以检测以下功能:
  1. TCP/UDP consistent translation
  2. TCP simultaneous open
  3. TCP/UDP loopback translation
  4. TCP unsolicited connections filtered
  5. UDP unsolicited messages filtered

你可以在下载、编译运行这个C程序:natcheck.c (如果是64位电脑,可以在添加编译参数"-DHAVE_STDINT"或者直接修改程序的#define)
如果你想在Windows平台上运行NAT Check, 首先安装Windows上的GCC环境MinGW,然后使用-lws2_32编译选项编译即可)


 

Technical Explanation

这个程序使用的技术相当简单,并且已经被许多在线游戏和其它p2p应用广泛地使用。你可以在 here here 查看以前的讨论。

The Technique

假定通讯中的三台机器A,B,C。主机A是“well-known" intenet server,有固定的IP地址,它充当B和C通讯的”介绍人“角色。B和C都在NAT(可能是同一个NAT)的后面,都只有私网地址。其中B希望能通过 A的帮助,和C建立直接的p2p连接。
为了发起一个到C的p2p连接,B首先向A发送一条消息(UDP包,内容包含请求命令,B自己的本地地址和udp端口),请求”介绍“C。 A将C的真实IP和udp端口(也就是私网IP和端口)以及由A观察IP和端口(C经过NAT转换后的公网IP和端口)回复给B,同时A将B的这一对”地址/端口"信息发送给C。( 这里隐含C立刻向A发送udp响应的需求,否则,因为nat上的session过期,A无法得知C的正确的公网端口
现在B和C双方都知道建立一个p2p连接的需求,并且知道对方的公网地址/端口和本地地址/端口。双发尝试直接向对方发送udp包。如果两台机器正好在一个NAT后,则两者汇报的公网IP应该是相同的,这时B和C可以根据内网的地址/端口建立直接的连接。
大部分情况下,B和C在不同的子网内,他们各自的内网地址/端口是没有意义的。这时候,B和C需要向对方的公网地址/端口发送udp请求( 此时,他们各自使用的本地udp端口应该还是他们向A发送udp消息时的同一端口,这样,nat-cone nat-才会复用公网端口,并发起一个新的session),现在两个nat上都有目的ip/port是对方的udp连接session, 所以这时候到达的udp包不会被过滤。 因为发起连接有先后,所以,最初的几个到达对方nat的udp包会因为目标地址/端口不一致而被过滤。一旦双方的nat上都开启了新的session(称为hole)后,udp包将畅通无阻,这样,B和C之间的p2p连接就建立起来了。

Required NAT Behavior

以上技术的实现,有个重要的前提,那就是,NATS必须满足一个条件:对于每一对内部IP/Port(UDP),NAT只分配唯一的公网 IP/Port,而不是给每一个新的udp session分配新的udp公网端口。NAT上session是由源地址/端口对和目标地址/端口对两部分定义的。如果两个udp包的这两部分相同,那么NAT认为它们是一个session的,就会放行,否则会被过滤。
RFC 3022 explicitly allows and suggests that NATs behave in the former, "desirable" fashion, by maintaining a single (public IP, public port) mapping for a given (internal IP, internal port) combination independent of the number of active sessions involving this mapping. 这种behavior不仅有益于UDP应用的兼容,而且有利于NAT节省宝贵的公网端口地址。因为在session级上一样可以过滤进来的包,所以也不存在安全性方面的问题。NAT不采用此behavior的唯一考虑估计是为了省事,毕竟,新来一个session就新开一个端口在技术实现上要简单的多。
不幸的是,RFC 3022 does not require NATs to implement the desirable behavior。写这个小程序的一个目的也就是想知道现在的internet上到底有多少NATs是支持这种behavior的。 你可以将测试结果 提交到这里,或者 查看累计结果

Changes in Version 2

Version 2 of NAT Check contains the following enhancements:
  • 不再尝试猜测nat的类型,基本NAT还是NATP。因为大部分NATP会在绑定公私网端口的时候,首选相同的端口,这在表现形式上是和基本NAT是一样的。NAT Check碰到这种情况,就会误以为此NAT是Basic类型的。唯一的方法是在同一私网内的两台机器上同时运行NAT Check。
  • 可以测试NAT的一个特性: 回环转换(loopback translation, 是原文作者自己起的名称. 如果NAT支持回环转换,表示一台主机可以通过NAT赋予的公网地址和端口访问位于同一NAT后的私有网域中的另外一台主机。大部分的NAT可能还不支持这个功能,不过,它将会变得越来越重要,因为许多P2P客户端位于自己的NAT和ISP配置的公用NAT之后。(Twice-NAT[注:此处Twice-NAT术语来自于natcheck.c,"BAD for P2P over Twice-NAT", 当NAT不支持loopback translation时,p2p over Twice-NAT会有问题。据我的理解,Twice-NAT指两层NAT,而不是平常所说的Twice NAT,后者是NAT的一种新特性,可以同时更改IP包的源地址(端口)和目的地址(端口),解决nat内的IP地址和外部IP地址重叠的问题(IP overlapping)]
  • NAT Check 的命令行选项"-v", 打开它,你就鞥在测试过程中看到详细的反馈信息。 

What NAT Check Does

natcheck.c 本质上来讲,只是"ping" 两个不同的位于Internet上的服务器的众所周知的udp端口。这两台服务器都运行同样的程序natserver.c. 另外,还有第三台运行natbouncer.c 的"conspiring"服务器。前面的两台服务器只要收到udp请求,除了直接回复客户程序外,还会向第三台服务器发送一份,而这第三台服务器会将这个包回复给那个客户端,这个由第三台服务器发送的包不是客户端所期望的,属于“对方主动发起的”("unsolicited")。这个"bounce"的过程主要是测试NAT的安全性能,看它是否过滤这些"unsolicited"的包。

natcheck.c 会绑定同一本地端口向前两台公网服务器同时发送一些udp包,根据判断两台服务器的回复包中报告的客户端公网地址/端口是否相同来判定此NAT是否实现了上面所说的"desirable behavior",也就是同一内部ip/port发起的多个session只共享映射到nat上的一个公网ip/port对。

Related Links

防火墙 (Firewall)
防火墙限制了私网与公网的通信,它主要是将(防火墙)认为未经授权的的包丢弃,防火墙只是检验包的数据,并不修改数据包中的IP地址和TCP/UDP端口信息。
网络地址转换(NAT)
当有数据包通过时,网络地址转换器不仅检查包的信息,还要将包头中的IP地址和端口信息进行修改。以使得处于NAT之后的机器共享几个仅有的公网IP地址(通常是一个)。网络地址转换器主要有两种类型:

  1. 基础NAT (Basic NAT) :基础NAT 将私网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换。基础NAT一般用在当NAT拥有很多公网IP地址的时候,它将公网IP地址与内部主机进行绑定,使得外部可以用公网IP地址访问内部主机。
  2. 网络地址和端口转换 (Network Address/Port Translator NAPT):这是最普遍的情况,网络地址/端口转换器检查、修改包的IP地址和TCP/UDP端口信息,这样,更多的内部主机就可以同时使用一个公网IP地址。
请参考[NAT-TRAD]和[NAT-TERM]两个文档了解更多的NAT分类和术语信息。另外,关于NAPT的分类和术语,[STUN]在最近做了更多的定义。当一个内部网主机通过NAT打开一个“外出”的TCP或UDP会话时,NAPT分配给这个会话一个公网IP和端口,用来接收外网的响应的数据包,并经过转换通知内部网的主机。这样做的效果是,NAPT在 [私有IP:私有端口] 和[公网IP:公网端口]之间建立了一个端口绑定。

端口绑定指定了NAPT将在这个会话的生存期内进行地址转换任务。这中间存在一个这样的问题,如果P2P应用程序从内部网络的一个[私有IP地址:端口]对同时发出多条会话给不同的外网主机,那么NAT会怎样处理呢?请看以下几种方案。
  • 锥形NAT (Cone NAT) :当建立了一个 [私有IP:端口]-[公网IP:端口] 端口绑定之后,对于来自同一个[私有IP:端口]会话,锥形NAT服务器允许发起会话的应用程序 重复使用这个端口绑定,一直到这个会话结束才解除(端口绑定)。
  • 对称NAT (Symmetric NAT) :对称NAT,与Cone NAT是大不相同的,并不对会话进行端口绑定,而是分配一个全新的 公网端口 给每一个新的会话。(因为很难正确得知这个新分配的公网端口的具体数值,本文谈及的p2p udp hole punch技术并不适用于这种nat。事实上,对称nat已不多见

回环转换 (Loopback translation)
当NAT的私网内部机器想通过公共地址来访问同一台局域网内的机器的时,NAT设备等价于做了两次NAT的事情,在包到达目标机器之前,先将私有地址转换为公网地址,然后再将公网地址转换回私有地址。我们把具有上叙转换功能的NAT设备叫做“回环转换”设备。
更多内容,可以技术细节可参考 http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值