NAT穿透的详解及分析

1、什么是NAT?为何要使用NAT?
NAT是将私有地址转换为合法IP地址的技术,通俗的讲就是将内网与内网通讯时怎么将内网私有IP地址转换为可在网络中传播的合法IP地址。NAT的出现完美地解决了lP地址不足的问题,并且还可以有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。 
2、NAT的分类
STUN标准中,根据内部终端的地址(LocalIP:LocalPort)到NAT出口的公网地址(PublicIP:PublicPort)的影射方式,把NAT分为四种类型:
一、Full Cone NAT(彻底锥型):后端

        内网主机创建一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),之后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,任何外部主机只要知道这个(PublicIP:PublicPort)就能够发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。 
二、Restricted Cone NAT(限制锥型):安全

        内网主机创建一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),之后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,若是任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)而且内网主机以前用这个socket曾向这个外部主机IP发送过数据。只要知足这两个条件,这个外部主机就能够用本身的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。
三、Port Restricted Cone NAT(端口限制锥型):服务器

        内网主机创建一个socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),之后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,若是任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)而且内网主机以前用这个socket曾向这个外部主机(IP,Port)发送过数据。只要知足这两个条件,这个外部主机就能够用本身的(IP,Port)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包。
四、Symmetric NAT(对称型):网络

        内网主机创建一个socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),之后内网主机发送给外部主机1的全部数据都是用这个(PublicIP-1,Port-1),若是内网主机同时用这个socket给外部主机2发送数据,NAT会为其分配一个(PublicIP-2,Port-2), 之后内网主机发送给外部主机2的全部数据都是用这个(PublicIP-2,Port-2).若是NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不一样,若是NAT只有一个公网IP,则Port-1和Port-2确定不一样,也就是说必定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。此外,若是任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,而后才能往回发送,不然即便他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机,这种NAT没法实现P2P通讯,可是若是另外一方是Full Cone NAT,仍是能够实现穿透的,下面我会详细分析各类类型NAT穿透的状况。
  NAT 功能一般被集成到路由器、防火墙、ISDN路由器或者单独的NAT设备中。因此咱们你们不多会知道NAT,上面NAT类型的概念描述是比较通俗的,但为了更便于理解,我再举例阐述一下NAT的原理。
  现有通讯的双方A和B,当A和B都是在公网的时候,通讯是不用NAT的。假设A在内网,内网IP是192.168.1.3,端口号是5000,A通过NAT后的IP是221.221.221.100,端口号是8000,B的IP是202.105.124.100,端口是8500。若是B要去主动链接A,即便B知道A通过NAT后的IP和端口也是没法链接成功的,由于A没有向B(202.105.124.100:8500)发送过数据,因此B的数据包会被A的NAT丢弃,因而链接失败。可是A若是去主动链接B,因为B是在公网,因此会链接成功,通讯也就会创建。这也就是反弹链接木马“反弹”二字的精髓。
当客户端A和B都是处在内网的时候,双方因为都不知道对方的公网IP和端口,就会无从下手,因此要在客户端A和B之间架设一台服务器S来为它们牵线,并且S是处在公网,以保证A和B都能链接到S。客户端A和B登陆时都首先链接S,S就会知道A和B通过NAT后的IP和端口,当A想要链接B时,就像S发出请求,S会把B通过NAT后的IP和端口告诉A,同时S向B发送A通过NAT后的IP和端口,并要求B发送数据给A,B发送数据到达A时会被A的NAT抛弃,可是B的NAT会有B发送数据到A的记录,这是A再向B发送数据时就会被B的NAT放行,由于B曾经向A的外网IP和端口发送过数据。可能有点乱,下面以故事的形式叙述一下这个情景。
人物:A(男) NAT_A(A家接线员) B(女) NAT_B (B家接线员) S
场景介绍:A想认识B,可是不知道B的电话,S跟A、B都是朋友,而且知道A和B的电话。接线员的职责:对往外转接的电话不作询问,对往内转接的电话则要过滤以避免有骚扰电话。过滤规则:在必定时间内没有拨打过的号码就过滤。
首先A给S打电话:
A说:我想认识你朋友B,你把她电话给我呗。
S说:行,她的电话是PublicIP_B,我让她先给你打个电话,要不她家接线员不帮你转接。
A说:好。

S跟B打电话:
S说:我有一个朋友A,人挺好的,他想认识你,你给他打个电话,他的电话号码是PublicIP_A。
B说:行,打完告诉你。
S说:好的。

B打电话到A家,B家接线员NET_B看到女主人想往PublicIP_A打电话就转接到A家了,同时把号码PublicIP_A记录下来,A家接线员NAT_A一看号码是个近期没打过的号,就给挂断了。

B给S打电话:
B说:我打完电话了
S说:好,等着吧,一会他就给你打进来了。

S给A打电话:
S说:他给你打完电话了,你快点给她打。

A打电话到B家, A家接线员NET_A看到男主人想往PublicIP_B打电话就转接到B家了,B家接线员NET_B看到是刚刚拨过的PublicIP_A号码打过来的,就转接给B了,A和B的电话也就打通了。
A和B通话:
A说:电话终于打通了,想认识你挺困难的。
B说:是啊。


以上虽然和实际不太同样,但穿透的总体过程基本就是这样。A往B发送数据的惟一阻碍就是NET_B,因此想要成功发送数据,必须把NET_B穿一个洞,A是没法完成这项工做的,因此就得让B完成这个打洞操做,也就是让B往A发送数据,这样NET_B就会误觉得A发送的数据是上次会话的一部分从而不予阻拦。
可是,因为NAT的类型没有一个统一的标准,因此NAT穿透使用的技术有不少种,穿透的成功率也不同。还有些NAT类型的内网之间几乎没法穿透。下面咱们用实例详细分析一下各类NAT类型穿透的可行性。

A机器在私网(192.168.0.3) 
A侧NAT服务器(221.221.221.100) 
B机器在另外一个私网(192.168.0.5) 
B侧NAT服务器(210.30.224.70) 
C机器在公网(210.202.14.36)做为A和B之间的中介 
A机器链接C机器,假使是A(192.168.0.3:5000)-> A侧NAT(转换后221.221.221.100:8000)-> C(210.202.14.36:2000) 
B机器也链接C机器,假使是B(192.168.0.5:5000)-> B侧NAT(转换后210.30.224.70:8000)-> C(210.202.14.36:2000) 
A机器链接过C机器后,A向C报告了本身的内部地址(192.168.0.3:5000),此时C不只知道了A的外部地址(C经过本身看到的221.221.221.100:8000)也知道了A的内部地址。同理C也知道了B的外部地址(210.30.224.70:8000)和 内部地址(192.168.0.5:5000)。以后,C做为中介,把A的两个地址告诉了B,同时也把B的两个地址告诉了A。 
假设A先知道了B的两个地址,则A从192.168.0.3:5000处同时向B的两个地址192.168.0.5:5000和210.30.224.70:8000发包,因为A和B在两个不一样的NAT后面,故从A(192.168.0.3:5000)到B(192.168.0.5:5000)的包确定不通,如今看A(192.168.0.3:5000)到B(210.30.224.70:8000)的包,分以下两种状况: 
一、B侧NAT属于Full Cone NAT 
        则不管A侧NAT属于Cone NAT仍是Symmetric NAT,包都能顺利到达B。若是程序设计得好,使得B主动到A的包也能借用A主动发起创建的通道的话,则即便A侧NAT属于Symmetric NAT,B发出的包也能顺利到达A。 
结论1:只要单侧NAT属于Full Cone NAT,便可实现双向通讯。 
二、B侧NAT属于Restricted Cone或Port Restricted Cone 
则包不能到达B。再细分两种状况 
(1)、A侧NAT属于Restricted Cone或Port Restricted Cone 
        虽然先前那个初始包未曾到达B,但该发包过程已经在A侧NAT上留下了足够的记录:A(192.168.0.3:5000)->(221.221.221.100:8000)->B(210.30.224.70:8000)。若是在这个记录没有超时以前,B也重复和A同样的动做,即向A(221.221.221.100:8000)发包,虽然A侧NAT属于Restricted Cone或Port Restricted Cone,但先前A侧NAT已经认为A已经向B(210.30.224.70:8000)发过包,故B向A(221.221.221.100:8000)发包可以顺利到达A。同理,此后A到B的包,也能顺利到达。 
结论2:只要两侧NAT都不属于Symmetric NAT,也可双向通讯。换种说法,只要两侧NAT都属于Cone NAT,便可双向通讯。 
(2)、A侧NAT属于Symmetric NAT 
         由于A侧NAT属于Symmetric NAT,且最初A到C发包的过程在A侧NAT留下了以下记录:A(192.168.0.3:5000)->(221.221.221.100:8000)-> C(210.202.14.36:2000),故A到B发包过程在A侧NAT上留下的记录为: 
A(192.168.0.3:5000)->(221.221.221.100:8001)->B(210.30.224.70:8000)(注意,转换后端口产生了变化)。而B向A的发包,只能根据C给他的关于A的信息,发往A(221.221.221.100:8000),由于A端口受限,故此路不通。再来看B侧NAT,因为B也向A发过了包,且B侧NAT属于Restricted Cone或Port Restricted Cone,故在B侧NAT上留下的记录为:B(192.168.0.5:5000)->(210.30.224.70:8000)->A(221.221.221.100:8000),此后,若是A还继续向B发包的话(由于同一目标,故仍然使用前面的映射),若是B侧NAT属于Restricted Cone,则从A(221.221.221.100:8001)来的包可以顺利到达B;若是B侧NAT属于Port Restricted Cone,则包永远没法到达B。 
结论3:一侧NAT属于Symmetric NAT,另外一侧NAT属于Restricted Cone,也可双向通讯。 
反过来想,则能够得出另外一个结论:两个都是Symmetric NAT或者一个是Symmetric NAT、另外一个是Port Restricted Cone,则不能双向通讯,由于NAT没法穿透;(me:symmetricNAT之因此难以穿透是由于:AB“汇报”给S的外部端口与链接A/B时的端口不一样所致。由于与不一样主机通讯时,NAT为其分配不一样外部端口。) 
上面的例子虽然只是分析了最初发包是从A到B的状况,可是,因为二者的对称性,前面得出的几条结论没有方向性,双向都适用。 
咱们上面得出了四条结论,natcheck网站则把他归结为一条:只要两侧NAT都属于Cone NAT(含Full Cone、Restricted Cone和Port Restricted Cone三者),便可双向通讯。没有把咱们的结论3包括进去。
通常状况下,只有比较注重安全的大公司会使用Symmetric NAT,禁止使用P2P类型的通讯,不少地方使用的都是Cone NAT,所以穿透技术仍是有发展前景的。
3、使用UDP、TCP穿透NAT
上面讲的状况能够直接应用于UDP穿透技术中,使用TCP 协议穿透NAT 的方式和使用UDP 协议穿透NAT 的方式几乎同样,没有什么本质上的区别,只是将无链接的UDP 变成了面向链接的TCP 。值得注意是:
一、 B在向A打洞时,发送的SYN 数据包,并且一样会被NAT_A 丢弃。同时,B须要在原来的socket 上监听,因为重用socket ,因此须要将socket 属性设置为SO_REUSEADDR 。
A向B发送链接请求。一样,因为B到A方向的孔已经打好,因此链接会成功,通过3 次握手后,A到B之间的链接就创建起来了。具体过程以下:
(me:UDP过程不须要建立两个socket,过程与上述描述的方法一致,不需再罗列)
一、 S启动两个网络侦听,一个叫【主链接】侦听,一个叫【协助打洞】的侦听。
二、 A和B分别与S的【主链接】保持联系。
三、 当A须要和B创建直接的TCP链接时,首先链接S的【协助打洞】端口,并发送协助链接申请。同时在该端口号上启动侦听。注意因为要在相同的网络终端上绑定到不一样的套接字上,因此必须为这些套接字设置 SO_REUSEADDR 属性(即容许重用),不然侦听会失败。
四、 S的【协助打洞】链接收到A的申请后经过【主链接】通知B,并将A通过NAT-A转换后的公网IP地址和端口等信息告诉B。
五、 B收到S的链接通知后首先与S的【协助打洞】端口链接,随便发送一些数据后当即断开,这样作的目的是让S能知道B通过NAT-B转换后的公网IP和端口号。
六、 B尝试与A的通过NAT-A转换后的公网IP地址和端口进行connect,大多数路由器对于不请自到的SYN请求包直接丢弃而致使connect失败,但NAT-B会纪录这次链接的源地址和端口号,为接下来真正的连 接作好了准备,这就是所谓的打洞,即B向A打了一个洞,下次A就能直接链接到B刚才使用的端口号了。
七、 客户端B打洞的同时在相同的端口上启动侦听。B在一切准备就绪之后经过与S的【主链接】回复消息“我已经准备好”,S在收到之后将B通过NAT-B转换后的公网IP和端口号告诉给A。
八、 A收到S回复的B的公网IP和端口号等信息之后,开始链接到B公网IP和端口号,因为在步骤6中B曾经尝试链接过A的公网IP地址和端口,NAT-B纪录了这次链接的信息,因此当A主动链接B时,NAT-B会认为是合法的SYN数据,并容许经过,从而直接的TCP链接创建起来了。并发

==================================== 另外一遍 ===================================================socket

简述

基于UDP的P2P应用须要考虑NAT的类型,由于不一样的NAT组合的穿透的方式并不一致,有的能通, 有的不能通。tcp

通常来说, NAT能够分为四种类型,分别是:网站

1, 全锥型(Full Cone)spa

2,  受限锥型(Restricted Cone), 或者说是IP受限锥型.net

3,  端口受限锥型(Port Restricted Cone), 或者说是IP + PORT受限锥型

4,  对称型(Symmetric)

其中1,2,3属于同一种类型,都是锥型,区别只是路由器的不一样的安全策略。

还有些NAT不属于这四种中的任何一种,就不在本文的讨论范围了。

为何有四种类型的NAT

  NAT缓解了IPV4地址不够用的问题,同时也也带了限制,那就是NAT外部的主机没法主动跟位于NAT内部的主机通讯,NAT内部主机想要通讯,必须主动和公网的一个IP通讯,路由器负责创建一个映射关系,从而实现数据的转发, 这就是NAT的工做原理。

假定

公网server1 ip是1.1.1.1, 监听端口是1111

公网server2 ip是2.2.2.2, 监听端口是2222

NAT router ip是8.8.8.8

NAT内部client是192.168.0.3

client发送数据的时候,无论是tcp仍是udp必须本地绑定一个端口,通常来说,这个过程都是自动的。

假定client(192.168.0.3, 100)给 server(1.1.1.1, 1111)发送报文,报文到达路由器,路由器在本身的公网ip上开辟一个端口800,从而创建了一个隐射关系(8.8.8.8, 800)<--->(192.168.0.3, 100),  创建映射关系后,因此(192.168.0.3, 100)和(1.1.1.1, 1111)之间的报文都经过这个映射关系进行转发。

NAT之间主要的区别分两种状况讨论

1. client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上创建好映射关系后,若是client(192.168.0.3, 100)又给(2.2.2.2, 2222)发送数据,路由器该怎么处理呢?

  1,  复用旧的映射关系(8.8.8.8, 800)<--->(192.168.0.3, 100)和(2.2.2.2, 2222)通讯, 这就是锥型(Cone) NAT

  2,  建立新的映射关系(8.8.8.8, 801)<--->(192.168.0.3, 100)和(2.2.2.2, 2222)通讯, 这就是对称型NAT

  注:  (8.8.8.8, 801)只是举例,到底用什么端口取决于路由器的端口管理策略,总之是另外的一个端口,有的路由器有多个公网IP,不一样的IP也会参与到这个映射关系中。

2. client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上创建好映射关系后,若是这个时候路由器(8.8.8.8)在800端口上收到从另一台server(2.2.2.2, 2222)发来的数据,是否是应该转发给(192.168.0.3, 100)呢?

  有四种状况:

  1, 无条件转发给(192.168.0.3, 100), 这就是全锥型(Full Cone)NAT。

  2, 若是(192.168.0.3, 100)以前给(2.2.2.2)发送过数据,则转发, 这就是受限锥型(Restricted Cone)。

  3, 若是(192.168.0.3, 100)以前给(2.2.2.2, 2222)发送过数据,则转发, 这就是端口受限锥型(Port Restricted Cone)。

  4, 丢弃报文,拒绝转发, 这就是对称型NAT。

从上面也描述也能够看出,安全性系数,  对称型 > 端口受限锥型 > 受限锥型 > 全锥型

 

不一样NAT的穿透性

NAT有10种组合


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

转自:https://blog.csdn.net/g_brightboy/article/details/12704933

原文:https://blog.csdn.net/mycloudpeak/article/details/53550405 

相关文章
相关标签/搜索