TCP穿透NAT,第1张

谈谈我的理解:

首先,tcp不同于udp,tcp天生就是不对等的连接,因此穿透nat就显得很困难。

最为简单的一种方式:

客户端:a,b

服务器端(公网)c

a发送消息给c,同时c拿到a的ip端口等信息,将a提出的请求转发给已与c连接的b,b表示同意后发送消息给c,c将消息反馈给a,同时为a和b的通信做准备(分配端口等等),整个过程是客户端到服务器再到客户端,c起中转作用,a与b建立连接实际是a与c,b与c建立的连接。

一般对于可靠性要求较低的应用会使用udp实现。

优点:适用于所有类型网络,简单;

缺点:占用带宽,速度慢。

早期的msn就是这种方式。

第二种方式:TCP的p2p技术。

这种方式是目前最热门的,我也正在看。

转一下来自cmu(卡耐基梅隆)牛人们的研究:

××××××××××××××××

原文:http://wwwandrewcmuedu/user/ggw/WBFDpdf

由于工作需要,在网上找了很长时间P2P的资料,好像只有《P2P 之 UDP穿透NAT的原理与实现(附源代码)》比较有实际意义,可惜又是用UDP实现的,无奈只好找了份英文资料啃,发现很有参考价值,就根据理解翻译了一部分,分享给大家,由于水平有限,有错望多多包涵。如果有人能够继续翻译下去别忘了通知我哦呵呵,wanfeng_001@126com,感谢。

摘要

防火墙和网络地址转换(NAT)设备对于传统的P2P协议存在一定的问题。一些中间设备抑制了来自外部网络到内部网络的TCP请求,这篇文章的目的就是寻找一个能够在两个NAT设备内部的主机间建立TCP连接的方法。我们已经在两个普通的硬件条件下实现了这个功能。

1入门

由于32位IP地址的减少,现在出现了很多通过一个internet地址代理内部网络上网的设备,这就是NAT技术。这些设备对于INTERNET已经越来越重要了,但是它们的独立发展因为缺乏标准而对现在的internet协议造成危害。

2技术

典型的NAT和防火墙设备都是不允许外部地址主动请求而进入内部网络的,如果用户的程序需要在两个内部网络间建立直接性的连接,那么两个内部设备之间必须是相互信任的。如果A和B两个部分都初始化了TCP连接,NAT设备就会认为它们之间是相互信任的,也就允许它们之间的连接了。

图1是一个例子,目标是能够让A和B(分别在NATA和NATB后)建立TCP连接。

我们讨论了多种在特定的NAT设备环境下的TCP连接方案。

如果我们的情况如下:

1、可预测NA的端口,可预测NB的端口,可指定源IP的特定路由

2、可预测NA的端口,可预测NB的端口,不可指定源IP的特定路由

3、随机的NA端口,可预测NB的端口,可指定源IP的特定路由

4、随机的NA端口,可预测NB的端口,不可指定源IP的特定路由

5、随机的NA端口,随机的NB端口,可指定源IP的特定路由

6、随机的NA端口,随机的NB端口,不可指定源IP的特定路由

我们必须作出这4种假设:

1、 两个主机都不受NAT设备所限制;

2、 我们可以配置网络设备使得主机看不到来自外部网络的ICMP包(TTL超过限制),因为这些ICMP数据包无论被任何一方接收到都是中断TCP连接。我们讨论的一些解决方案就依赖通过发送一个初始TTL很小的SYN包来建立TCP连接。一旦SYN包被路由器丢弃,ICMP TTL 超时包就会被传送到NAT设备,我们不允许NAT设备将这个超时TTL的返回包传送到内部网络,即使NAT会将这个包传送到内部,也需要通过配置防火墙来限制这个包到达主机;

3、 即使NAT设备看到ICMP超时的数据包,设备本身的映射表将不会作任何改动;

4、 内部网络的其它主机不会占用抢占这个端口,因为如果网络特别繁忙,这个端口可能会无效。

31第一种情况

我们可以通过图2表示的顺序解决问题:

1)A和B可以设定LSR(IP报头中的一个选项)通过X路由发送SYN数据包

2)X可以缓存它们的数据包并且发送欺骗的SYN+ACKS给NA和NB

3)A和B可以通过由X发送来的数据进行应答

4)X丢弃这两个ACK包,因为它已经可以确定A和B相互应答成功

图2是假设A和B都事先彼此的NAT的通信端口,A知道B的通信端口是NB:5000,B知道A的是NA:4000,并且要求X不在任何NAT设备的后面实际中这两个端口是预测得到的,预测过程如图3:

32第二种情况

第一种情况依赖与自由设定路由,但是现在很多路由器大多都限制这样做,并且会丢弃这样的服务请求包。因此在实际应用中,这种方案失败的可能性很大。如果自由设定路由不可行,我们可以通过out-of-band通道(他们预先与X连接好的TCP连接)来传送原本必须将数据包路由到X才能看到的包。注意在图二的第二步X已经知道了TCP的序号Q和P,因为X已经收到了这两个SYN包,但是如果数据包没有路由经过X就不可能收到它们。为了初始化这个连接,两个主机发送初始SYN包,并且他们都知道是不可能到达目标的,但是它们都可以记住自己的SYN号(个人看法,通过钩子获得发送的数据SYN包)并且可以发送给X,X得到了它们的SYN包,就可以欺骗它们发送ACK包了。有两种方法可以发送无法到达目标的数据包。简单的方法就是每个主机发送一个SYN给对方,要求应答包不会到达内部网络如果NAT(防火墙)会将应答包传回给内部网络,通常是发送TCP的reset包(RST),如果NAT生成RST包,A和B就不能简单地发送一个向图2中SYN给彼此,因为如果这样NA和NB就无法打洞了呵呵,如果NAT不发送RST包,那么这个TCP连接就不会被中断。另外一个发送无法到达目标网络的SYN包的方法是减小TTL值,使它们无法彼此到达。如果用户无法配置防火墙丢弃这个ICMP应答包,或者NAT不继续传送这个ICMP,这个TCP就不会立即关闭。这个解决方案不能使用一种简单的欺骗,因为我们必须保证源地址的SYN包发送者不会没有收到ICMP的RST包,否则会导致中间设备建立错误路由仅仅依靠SYN包,NAT就可以建立从internet IP和端口到外部IP和端口的路由由于欺骗的SYN包是错误的源IP(并非发出者X),这个路由将不会发送到X而是发送到NA或者NB。另外,这种方案都需要设置TTL到足够小,以便于对方的NAT不会收到到各自发出的初始SYN包,否则就无法完成打洞。(图4)

33第三种情况

比前两种简单,但是X将无法预见NA或者NB的端口。B将先给X发送一个SYN包告诉以便于X知道它所选用的端口号,然后X将这个信息发送到A,A就可以向这个确定的地址和端口发送SYN,图5是第一种情况的变形::

1)X向图3一样预测端口,但是它不能预测到NA的下一个端口号,但是可以预测NB的下一个端口号是5000,并且可以通知A和B这个节点已经建立了连接;

2)A和B同步节点X;

3)X可以欺骗A和B;

4)A和B相互发送ACK;

5)X丢弃发给它的ACK,因为它已经可以确认它们已经建立连接。

××××××××××××××××

第三种:实现***,通过安全的虚拟连接实现,而这样的话就不存在穿透问题,因为***是个虚拟网络,tcp在其中是被信任的。

NAT 俗称网络地址转换,基本 NAT 都部署在路由器或者交换机上。

主要还是IP地址的不足,使用少量的公有IP 地址代表较多的私有IP 地址的方式,将有助于减缓可用的IP地址空间的枯竭。用大白话:比如你有一个路由器(家用的那种就可以)这个路由器本身链接了公网(被分配到了一个公网的IP地址)。路由器后面有接了N多个设备,每个设备都分配到了一个私有的地址(内网地址),这些地址可以通过这个路由器和外网交互(并非是代理的中继方式)。

1 基本NAT: 这种NAT下的私有IP只有少部分(并不是全部)可以和外网通讯。每次这些私有地址向外网发送数据的时候,NAT就会把这个数据报的 源地址IP 修改成NAT的 公网地址 (这样接收方以为这个数据报是从NAT发给我的,我后面数据报在会给这个NAT就好了),并在NAT内存下对应的 映射关系 (端口和内网私有IP的映射)。当NAT收外网的数据报的时候,根据数据报的端口号找到内网的私有IP地址,将这个数据报的目的IP地址修改成内网私有IP地址(整个过程NAT负责了IP地址来回替换,辅助完成了内网机器和外网设备通讯,这里的外网设备有可能也是一个NAT)。如果收到的数据报在映射表中找不到对应映射,这个数据报就会被丢弃。

存在问题: 基本的NAT由于不会改动端口信息,当内部2个不同机器(2个不同的私有IP)使用同样的端口会出现映射错误了。

2 NPAT: 这类的NAT是在基本NAT基础上演化而来,它不仅修改 IP地址 还有 端口号 。基本可以满足NAT内全部的网络访问要求。NAT内的私有IP地址第一次向外网发送数据,NAT会选一个 映射表 里面还没有被使用过的 端口号 ,然后修改 发送数据报 的 源IP地址 和 源端口号 并发送出去,并把 私有IP地址 和 源端口号 ,和修改后的 端口号 映射关系记录下来。之后这个私有IP地址发送数据会首先判别之前是不是已经有这个映射关系,如果有就继续按照映射关系修改数据报。当NAT收到外部的数据,会从映射表找到对应关系。修改数据报的 目的IP地址 和 目的端口号 ,如果映射表中没有记录这个数据报就会被丢弃了。

解决了基础NAT的端口问题: 通过修改端口的可以让NAT内的多个私有IP地址可以使用相同的端口进行通信。因为NPAT更加灵活所以现在基本的NAT技术就是指的NPAT技术。

如果2台机器在同一个NAT下,那么他们可以直接通信了。

情况 1: 如果2台机器有一台在NAT下另一个在外网,那么只能NAT内的私有机器主动链接外网机器,因为外网的机器主动链接内网的机器,NAT映射表并不存在这个数据转发项,这个数据报就被丢弃了。

情况 2: 如果2台机器都在不同的NAT下,那么不管哪一方发起链接请求数据报都不会到达对应的机器。这种情况非常常见。

那么最简单的方式解决上面2个问题:就是在公网部署一台 中继服务器 ,双方机器都链接这台服务器。然后 中继服务器 帮助这2台服务器转发数据。这种方式最简单也是效率最低的。

到这里P2P正式登场了: 比如有下面这样的网络拓扑结构(就是上面情况2)

如果 NAT-A, IP:40325125 和 NAT-B, IP:2341238 需要直接通信的话,基本不可能,所以需要做些手段。

假设需要 手机 (图中)建立TCP链接到 电脑 (图中)需要如下手续:

1 由被链接方发送数据报(可以是UDP甚至是TCP的SYNC握手包)

[上传失败(image-4b61ae-1528199423593)]

绿色线表示了数据报流动的方向

图中 电脑 给 NAT-A IP:40325125 / 端口:4553 发出了一个数据报,这个数据报在经过 NAT-B 的时候 源IP地址 被修改成了 NAT-B的IP地址2341238 , 源端口 被修改成了 678 。这个数据报在到达 NAT-A 的时候,在映射表中找不到 678 端口对应的内部私有IP的映射。所以这个数据报一定会被 NAT-A 丢弃掉。但是经过这次数据报发送,在 NAT-B 的映射表里面就会标记 40325125:4553 我已经发送过数据过去了,那么后面只要从这个地址发送来的数据报,我就可以转发到内网正确的设备上面。

2 完成第一步后,链接方可以发起数据请求

p2p可以合理的利用互联网的资源,比如两个人视频聊天。完全可以通过p2p打穿NAT后互发数据(QQ就是这么办的)。但是有的时候设备之间的直连性能很差,比如:电信的用户和移动的用户视频。这个问题是ISP厂商之间的过渡带宽太窄,就算是设备直连但是依旧速度不快。所以这里情况下需要自己搭建服务器中继(中继也不是完全无作用)。这个服务器就是网关的作用,一般有多个网卡。不同的网卡对接不同的ISP厂商,然后互相转发。

利用P2P点对点技术实现,需解决的两个问题。

1实现内网之间机器的网络通信。

2需要解决UDP出现的数据传输不稳定问题。

假设一台在NAT211133后的192168177:8000要向NAT211134后的192168188:9000发送数据,假设你向211134这个IP地址的9000端口直接发送数据包,则数据包在到达NAT211134之后,会被当做无效非法的数据包被丢弃,NAT在此时相当于一个防火墙,会对没有建立起有效SESSION的数据包进行拒绝转递。当然,你也不能直接用内网地址192168188进行发送数据包,这就好比你在广州要打电话到上海的某个地方,如果你不加区号,直接拨打区域内电话是件很愚蠢的事。

首先我们要认识NAT设备,NAT英文全拼是Network Address Translator(网络地址转换器),说白了就是凡是经过NAT发出去的数据包,都会通过一定的端口转换(而非使用原端口)再发出去,也就是说内网和外网之间的通信不是直接由内网机器与外网NAT进行,而是利用内网对外网的NAT建立起SESSION与外网NAT的SESSION进行。

根据SESSION的不同,NAT主要分成两种:SymmetricNAPT以及CONE NAPT。简单的说,Symmetric NAPT是属于动态端口映射的NAT,而CONE NAPT是属于静态端口映射的NAT。而市场上目前大多属于后者,CONE的意思就是一个端口可以对外部多台NAT设备通信。这个也正是我们做点对点穿透的基本,是我们所希望的,否则现在的大部分点对点软件将无法正常使用。

像上面的例子,NAT211133和NAT211134之间需要进行通信,但开始不能直接就发数据包,我们需要一个中间人,这个就是外部索引服务器(我们假设是211135:7000),当NAT211133向211135:7000发送数据包,211135:7000是可以正常接收到数据,因为它是属于对外型开放的服务端口。当211135:7000收到数据包后可以获知NAT211133对外通信的临时SESSION信息(这个临时的端口,假设是6000会过期,具体的时间不同,但我个人的测试是每30秒发送一个心跳包keep住连接以保证端口维持住通信连接不断开),索引服务器此时应将此信息保存起来。而同时,NAT211134也在时刻向索引服务器发送心跳包,索引服务器就向NAT211134发送一个通知,让它向NAT211133:6000发送探测包(这个数据包最好多发几个),NAT211134在收到通知包之后再向索引服务器发送反馈包,说明自己已经向NAT211133:6000发送了探测包,索引服务器在接收到反馈包之后再向NAT211133转发反馈包,NAT211133在接收到数据包之后再向原本要请求的NAT211134发送数据包,此时连接已经打通,实现穿透,NAT211134会将信息转发给192168188的9000端口。

对于Symmetric NAPT的情况,网上有人说可以通过探测端口的方式,不过成功率并不高,我建议可用服务器进行中转。另外,最好在数据包发送前先检测是否进行的是同个NAT的情况,也就是内网发内网,如果是,直接发送即可,而无需通过外网再绕回来。

其次关于第二点,解决UDP传输的不稳定问题,其实这里涉及到另一个方面的知识,就是滑动窗口的东西,可以开一个缓冲区用于循环接收数据以及重组,另外加上超时重发机制以及确认发送机制,有点像TCP的传输原理,不过如果处理的好,效率绝对比采用TCP的方式要高。

  不知道你说的是不是计算机的NAT穿越技术?

  NAT分类

  • Full Cone NAT(完全圆锥型)

  • Address Restricted Cone NAT(地址限制圆锥型 )

  • Port Restricted Cone NAT(端口限制圆锥型)

  • Symmetric NAT(对称型)

  在这里:http://hibaiducom/oceaning/blog/item/b42544f41198886cddc474e9html

  ----------------------------------------------------------------------

  IP的防火墙/NAT穿越技术

  对IP地址资源需求的迅速增加超出了最初预期和设计的32比特(IPv4地址长度)。很多专家学者,尤其是IP标准领域的主导性国际组织IETF一直把IPv6看作是一种长期的IP地址短缺的解决方案,把网络地址翻译(NAT)看作是一种中短期的地址短缺解决方案。NAT的大量使用,使得在协议设计中将IP地址作为通信标志符的VoIP协议无法正常工作。目前已经出现了多种典型的穿越技术,有些还在发展中。比较典型的有:

  ·应用网关(ALG:Application Level Gateway):是最早出现的NAT穿越解决方案,在传统的NAT上进行协议扩展,使之具备感知SIP、H323、H324和MGCP等VoIP呼叫控制协议的能力,从而完成呼叫控制协议的解析和地址翻译功能。

  ·代理技术:是为缓解ALG方式所带来的现有NAT升级困难而出现的,它也是目前中国国内比较看好的一种NAT穿越解决方案,已经得到ITU-T的支持。

  ·隧道/***机制:逻辑上由隧道客户端和隧道服务器两部分构成,隧道客户端和隧道服务器通过隧道协议建立一条隧道,实现信令和媒体流透明穿越NAT。

  ·MIDCOM技术:是为了解决ALG和代理技术所共有的可扩展性不强而出现的一种NAT穿越解决方案,采用可信的第三方(MIDCOM Agent)对Middlebox(NAT)进行控制,由MIDCOM Agent控制Middlebox打开和关闭媒体端口。

  ·单边自我绑定地址(UNISAF: Unilateral Self-Address Fixing):RFC3424定义的UNSAF技术,可以让位于NAT后的一个客户设法发现位于NAT公网一侧的该客户的地址,然后让应用使用新学习到的地址而不是它自真正的IP地址。这样做需要在NAT公网一侧增加一个UNSAF服务器,并且修改客户端,以便让UNSAF服务器知道如何使用该 UNSAF服务器,而真正的应用服务器并不改变,典型的UNSAF技术包括STUN,TURN等。

  ·服务器做NAT导航(SINN:Server Involvement in NAT Navigation):修改服务器,改变对应用的真正处理,这种改变可能会违反应用标准本身的规定。但在某些应用协议中,SINN技术允许不改变客户端或NAT就可以实现NAT的穿越。这种技术能否使用完全取决于应用层协议,通常会对客户端的行国有一个假设。典型应用就是SIP中的会话控制器(SBC)。

  ·协议扩展:是针对各个信令协议的特点,在信令消息中增加新的消息参数,或者对原有的呼叫流程进行改进,使之可以工作在NAT环境中。该方案的优点是无需对现有NAT设备进行改动,缺点是现有的终端和软交换设备、网守和SIP服务器等控制设备需要同时进行扩展。因此协议扩展时应重点考虑协议的向下兼容问题,以保证与示扩展的终端的完整互通性。

  ·IPv6:如果一种穿越技术需要修改全部的相关部分,那就是IPv6了。

在现实Internet网络环境中,大多数计算机主机都位于防火墙或NAT之后,只有少部分主机能够直接接入Internet。很多时候,我们希望网络中的两台主机能够直接进行通信(即所谓的P2P通信),而不需要其它公共服务器的中转。由于主机可能位于防火墙或NAT之后,在进行P2P通信之前,我们需要进行检测以确认它们之间能否进行P2P通信以及如何通信。这种技术通常被称为NAT穿透(NAT Traversal)。最常见的NAT穿透是基于UDP的技术(如下面的RFC3489/STUN),也有基于TCP的穿透技术。NAT穿透技术最重要的是识别目标主机的NAT类型,这也是本文所要介绍的内容。

NAT有两大类,基本NAT和NAPT。

静态NAT:一个公网IP对应一个内部IP,一对一转换

动态NAT:N个公网IP对应M个内部IP,不固定的一对一转换关系

现在基本使用这种,又分为对称和锥型NAT。

锥型NAT ,有完全锥型、受限制锥型、端口受限制锥型三种:

对称NAT ,把所有来自相同内部IP地址和端口号,到特定目的IP地址和端口号的请求映射到相同的外部IP地址和端口。如果同一主机使用不同的源地址和端口对,发送的目的地址不同,则使用不同的映射。只有收到了一个IP包的外部主机才能够向该内部主机发送回一个UDP包。对称的NAT不保证所有会话中的(私有地址,私有端口)和(公开IP,公开端口)之间绑定的一致性。相反,它为每个新的会话分配一个新的端口号。

在RFC3489/STUN[1]中,基于UDP的NAT(Network Address Translation)穿透技术把主机划分为如下七种NAT类型:

UDP Blocked、Open Internet、Symmetric Firewall、Full Cone NAT、Restricted Cone NAT、Port Restricted Cone NAT、Symmetric NAT。具体解释如下:

(1) Open Internet :主机具有公网IP,允许主动发起和被动响应两种方式的UDP通信。

(2) UDP Blocked :位于防火墙之后,并且防火墙阻止了UDP通信。

(3) Symmetric Firewall :主机具有公网IP,但位于防火墙之后,且防火墙阻止了外部主机的主动UDP通信。

(4) Full Cone NAT :当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个固定的公网{IP:端口}。此后,通过这个socket发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;同时,任何外部主机都可以使用这个公网{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个映射表,内网主机的内网{IP:端口}与公网{IP:端口}是一一对应的关系。一旦这个映射关系建立起来(内部主机向某一外部主机发送一次数据即可),任何外部主机就可以直接向NAT内的这台主机发起UDP通信了,此时NAT透明化了。

(5) Restricted Cone NAT :当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个公网{IP:端口}。此后,通过这个socket向外发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;而任何收到过从这个socket发送来的数据的外部主机(由IP标识),都可以通过这个公网{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个内网{IP:端口}到公网{IP:端口}的映射,还维护了一个{外部主机IP, 公网{IP:端口}}到内网{IP:端口}的映射。因此,要想外部主机能够主动向该内部主机发起通信,必须先由该内部主机向这个外部发起一次通信。

(6) Port Restricted Cone NAT :当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个公网{IP:端口}。此后,通过这个socket向外部发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;一旦外部主机在{IP:端口}上收到过从这个socket发送来的数据后,都可以通过这个外部主机{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个从内网{IP:端口}到公网{IP:端口}的映射,还维护了一个从{外部主机{IP:端口}, 公网{IP:端口}}到内网{IP:端口}的映射。

(7) Symmetrict NAT :当内网主机创建一个UDP socket并通过它第一次向外部主机1发送UDP数据包时,NAT为其分配一个公网{IP1:端口1},以后内网主机发送给外部主机1的所有UDP数据包都是通过公网{IP1:端口1}发送的;当内网主机通过这个socket向外部主机2发送UDP数据包时,NAT为其分配一个公网{IP2:端口2},以后内网主机发送给外部主机2的所有UDP数据包都是通过公网{IP2:端口2}发送的。公网{IP1:端口1}和公网{IP2:端口2}一定不会完全相同(即要么IP不同,要么端口不同,或者都不同)。这种情况下,外部主机只能在接收到内网主机发来的数据时,才能向内网主机回送数据。

所谓锥形NAT 是指:只要是从同一个内部地址和端口出来的包,无论目的地址是否相同,NAT 都将它转换成同一个外部地址和端口。

“同一个外部地址和端口”与“无论目的地址是否相同”形成了一个类似锥形的网络结构,也是这一名称的由来。反过来,不满足这一条件的即为对称NAT 。

举例说明,假设:

NAT 内的主机 A : IP 记为 A ,使用端口 1000

NAT 网关 : IP 记为 NAT ,用于 NAT 的端口池假设为( 5001-5999 )

公网上的主机 B : IP 记为B ,开放端口 2000

公网上的主机 C : IP 记为C ,开放端口 3000

假设主机 A 先后访问主机 B 和 C

1 )如果是锥形 NAT :

那么成功连接后,状态必然如下:

A ( 1000 ) —— > NAT ( 5001 )—— > B ( 2000 )

A ( 1000 ) —— > NAT ( 5001 )—— > C ( 3000 )

也就是说,只要是从 A 主机的 1000 端口发出的包,经过地址转换后的源端口一定相同。

2 )如果是对称形 NAT :

连接后,状态有可能(注意是可能,不是一定)如下:

A ( 1000 ) —— > NAT ( 5001 )—— > B ( 2000 )

A ( 1000 ) —— > NAT ( 5002 )—— > C ( 3000 )

两者的区别显而易见。

三种CONE NAT之间的区别

仍然以上面的网络环境为例, 假设 A 先与 B 建立了连接:

A ( 1000 ) —— > NAT ( 5001 )——— > B ( 2000 )

1) Port Restricted Cone NAT:

只有 B ( 2000 )发往 NAT ( 5001 )的数据包可以到达 A ( 1000 )

该nat 将内网中一台主机的IP和端口映射到公网IP和一个指定端口,只有访问过的IP和端口可以通过映射后的IP和端口连接主机A

2) Restricted Cone NAT

只要是从 B 主机发往 NAT ( 5001 )的数据包都可以到达 A ( 1000 )

该nat 将内网中一台主机的IP和端口映射到公网IP和一个指定端口,只有访问过的IP可以通过映射后的IP和端口连接主机A

3) Full Cone NAT

任意地址发往 NAT ( 5001 )的数据包都可以到达 A ( 1000 )

该nat 将内网中一台主机的IP和端口映射到公网IP和一个指定端口,外网的任何主机都可以通过映射后的IP和端口发送消息

Linux的NAT

Linux的NAT“MASQUERADE”属于对称形NAT。说明这一点只需要否定 MASQUERADE 为锥形 NAT 即可。

linux 在进行地址转换时,会遵循两个原则:

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

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

假设如下的情况( 内网有主机 A 和 D ,公网有主机 B 和 C ):

先后 建立如下三条连接:

可以看到,前两条连接遵循了原则 1 ,并且不违背原则 2 而第三条连接为了避免与第二条产生相同的 socket 而改变了源端口比较第一和第三条连接,同样来自 A(1000) 的数据包在经过 NAT 后源端口分别变为了 1000 和1001 。说明 Linux 的 NAT 是对称 NAT 。

对协议的支持

CONE NAT 要求原始源地址端口相同的数据包经过地址转换后,新源地址和端口也相同,换句话说,原始源地址端口不同的数据包,转换后的源地址和端口也一定不同。

那么,是不是 Full Cone NAT 的可穿透性一定比 Symmetric NAT 要好呢,或者说,通过 Symmetric NAT 可以建立的连接,如果换成 Full Cone NAT 是不是也一定能成功呢?

假设如下的情况:

(内网有主机A和D,公网有主机B和C,某 UDP 协议服务端口为 2000 ,并且要求客户端的源端口一定为 1000 。 )

1)如果A使用该协议访问B:

A ( 1000 ) —— > NAT ( 1000 )——— > B ( 2000 )

由于 Linux 有尽量不改变源端口的规则,因此在 1000 端口未被占用时,连接是可以正常建立的如果此时D也需要访问B:

D ( 1000 ) —— > NAT ( 1001 )—X— > B ( 2000 )

端口必须要改变了,否则将出现两个相同的 socket ,后续由 B(2000) 发往NAT( 1000 )的包将不知道是转发给A还是D。于是B将因为客户端的源端口错误而拒绝连接。在这种情况下, MASQUERADE 与 CONENAT 的表现相同。

2)如果A连接B后,D也像C发起连接,而在此之后,A又向C发起连接

① A ( 1000 ) —— > NAT ( 1000 )——— > B ( 2000 )

如果是 MASQUERADE :

② D ( 1000 ) —— > NAT ( 1000 )——— > C ( 2000 )

③ A ( 1000 ) —— > NAT ( 1001 )—X— > C ( 2000 )

如果是 CONE NAT :

② D ( 1000 ) —— > NAT ( 1001 )—X— > C ( 2000 )

③ A ( 1000 ) —— > NAT ( 1000 )——— > C ( 2000 )

对于 MASQUERADE 来说,只要在没有重复的 socket 的情况下,总是坚持尽量不改变源端口的原则,因此第二条连接仍然采用源端口 1000 ,而第三条连接为了避免重复的 socket 而改变了端口。

对于 CONE NAT ,为了保证所有来自 A(1000) 的数据包均被转换为 NAT(1000) ,因此 D 在向 C 发起连接时,即使不会产生重复的 socket ,但因为 NAT 的 1000 端口已经被 A(1000) “占用”了,只好使用新的端口。

可以看出,不同的 target 产生不同的结果。我们也不能绝对的说,在任何时候,全锥形 NAT 的可穿透性都比对称 NAT 要好,比如上面的例子,如果只存在连接①和②,显然是对称形 NAT 要更适用。因此,选择哪种 NAT ,除了对网络安全和普遍的可穿透性的考虑外,有时还需要根据具体应用来决定。

输入和输出准备好后,附上一张维基百科的流程图,就可以描述STUN协议的判断过程了。

STEP2 :检测客户端防火墙类型 -- Test2

STUN客户端向STUN服务器发送请求,要求服务器从其他IP和PORT向客户端回复包:

a)收不到服务器从其他IP地址的回复,认为包前被前置防火墙阻断,网络类型为对称NAT;

b)收到则认为客户端处在一个开放的网络上,网络类型为公开的互联网IP。

STEP3 :检测客户端NAT是否是FULL CONE NAT -- Test2

客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用另一对(IP-2,Port-2)响应客户端的请求往回发一个数据包,客户端发送请求后立即开始接受数据包。 重复这个过程若干次。

a)如果每次都超时,无法接受到服务器的回应,则说明客户端的NAT不是一个Full Cone NAT,具体类型有待下一步检测(继续);

b)如果能够接受到服务器从(IP-2,Port-2)返回的应答UDP包,则说明客户端是一个Full Cone NAT,这样的客户端能够进行UDP-P2P通信。

STEP4 :检测客户端NAT是否是SYMMETRIC NAT -- Test1#2

客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port, 客户端发送请求后立即开始接受数据包。 重复这个过程直到收到回应(一定能够收到,因为第一步保证了这个客户端可以进行UDP通信)。

用同样的方法用一个socket向服务器的(IP-2,Port-2)发送数据包要求服务器返回客户端的IP和Port。

比较上面两个过程从服务器返回的客户端(IP,Port),如果两个过程返回的(IP,Port)有一对不同则说明客户端为Symmetric NAT,这样的客户端无法进行UDP-P2P通信(检测停止)因为对称型NAT,每次连接端口都不一样,所以无法知道对称NAT的客户端,下一次会用什么端口。否则是Restricted Cone NAT,是否为Port Restricted Cone NAT有待检测(继续)。

STEP5 :检测客户端NAT是Restricted Cone 还是 Port Restricted Cone -- Test3

客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用IP-1和一个不同于Port-1的端口发送一个UDP 数据包响应客户端, 客户端发送请求后立即开始接受数据包。重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端是一个Port Restricted Cone NAT,如果能够收到服务器的响应则说明客户端是一个Restricted Cone NAT。以上两种NAT都可以进行UDP-P2P通信。

一些说明:

[1] RFC3489中的STUN协议(Simple Traversal of UDP Through NATs)是一个完整的NAT穿透方案,但其修订版本(RFC5389)把STUN协议(Session Traversal Utilities for NAT)定位于为穿透NAT提供工具,并不提供一个完整的解决方案。此外,RFC3489只提供了UDP的NAT穿透,而RFC5389还支持TCP的穿透)。

Reference

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » TCP穿透NAT

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情