穿透NAT类型以及STUN、TURN简单介绍

概述

NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。NAT 可以让那些使用私有地址的内部网络连接到Internet或其它IP网络上,这个过程对用户来说是透明的。NAT路由器在将内部网络的数据包发送到公用网络时,在IP包的报头把私有地址转换成合法的IP地址。因此我们可以认为,NAT在一定程度上能够有效的解决公网地址不足的问题。

NAT的副作用以及解决方案

国内移动无线网络运营商在链路上一段时间内没有数据通讯后, 会淘汰NAT表中的对应项, 造成链路中断。

这是NAT带来的第一个副作用——NAT超时:

而国内的运营商一般NAT超时的时间为5分钟,所以通常我们TCP长连接的心跳设置的时间间隔为3-5分钟。

而第二个副作用就是——NAT墙。

NAT会有一个机制,所有外界对内网的请求,到达NAT的时候,都会被NAT所丢弃,这样如果我们处于一个NAT设备后面,我们将无法得到任何外界的数据。

但是这种机制有一个解决方案:就是如果我们A主动往B发送一条信息,这样A就在自己的NAT上打了一个通往B的洞。这样A的这条消息到达B的NAT的时候,虽然被丢掉了,但是如果B这个时候在给A发信息,到达A的NAT的时候,就可以从A之前打的那个洞中,发送给到A手上了。

NAT有4种不同的类型

  • Full Cone

这种NAT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A,不管是不是C发过来的(很少是这种类型)。
例如
A:192.168.8.100
NAT:202.100.100.100
C:292.88.88.88
A(192.168.8.100:5000) —— > NAT(202.100.100.100:8000) —— > C(292.88.88.88:2000)
任何发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

  • Address Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用任何端口和A通信.其他的外网机器不行。
例如
A:192.168.8.100
NAT:202.100.100.100
C:292.88.88.88

A(192.168.8.100:5000)—— >NAT(202.100.100.100 : 8000) —— > C(292.88.88.88:2000)
任何从C发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

  • Port Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用原来的端口和A通信.其他的外网机器不行。
例如
A:192.168.8.100
NAT:202.100.100.100
C:292.88.88.88

A(192.168.8.100:5000) —— > NAT(202.100.100.100 : 8000)—— > C(292.88.88.88:2000)
C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

以上三种NAT通称Cone NAT(圆锥形NAT),所谓锥形NAT 是指:只要是从同一个内部地址和端口出来的包,无论目的地址是否相同,NAT 都将它转换成同一个外部地址和端口。“同一个外部地址和端口”与“无论目的地址是否相同”形成了一个类似锥形的网络结构,也是这一名称的由来。反过来,不满足这一条件的即为对称NAT 。

我们只能用这种NAT进行UDP打洞

  • Symmetric(对称形)

对于这种NAT。连接不同的外部Server,NAT打开的端口会变化。也就是内部机器A连接外网机器B时,NAT会打开一个端口,连接外网机器C时又会打开另外一个端口。

Symmetric NAT会遵循两个原则:

  1. 尽量不去修改源端口,也就是说,ip 伪装后的源端口尽可能保持不变。
  2. 更为重要的是,ip 伪装后必须 保证伪装后的源地址/ 端口与目标地址/ 端口(即所谓的socket )唯一。
    假设如下的情况( 内网有主机 A 和 D ,公网有主机 B 和 C ):

先后建立如下三条连接:

A ( 1000 ) —— > NAT ( 1000 )—— > B ( 2000 )
D ( 1000 ) —— > NAT ( 1000 )—— > C ( 2000 )
A ( 1000 ) —— > NAT ( 1001 )—— > C ( 2000 )

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

锥形和对称形NAT的区别

  • 如果是锥形 NAT :

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

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

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

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

  • 如果是对称形 NAT :

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

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

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

两者的区别显而易见。

STUN和TURN的简单介绍

STUN Server主要做了两件事:

  • 接受客户端的请求,并且把客户端的公网IP、Port封装到ICE Candidate中。
  • 通过一个复杂的机制,得到客户端的NAT类型。

TURN Server也主要做了两件事:

  • 为NAT打洞:
    如果A和B要互相通信,那么TURN Server,会命令A和B互相发一条信息,这样各自的NAT就留下了对方的洞,下次他们就可以之间进行通信了。

  • 为对称NAT提供消息转发:
    当A或者B其中一方是对称NAT时,那么给这一方发信息,就只能通过TURN Server来转发了。

三种转发情形

STUN Server判断出客户端处于什么类型的NAT下,然后去做后续的处理,STUN Server会返回给客户端它的公网IP、Port和NAT类型,除此之外:

  • 如果A处于公网或者Full Cone Nat下,STUN不做其他的了,因为其他客户端可以直接和A进行通信。
    在这里插入图片描述

  • 如果A处于Restrict Cone或者Port Restrict NAT下,STUN还会协调TURN进行NAT打洞。

在这里插入图片描述

  • 如果A处于对称NAT下,那么点对点连接下,NAT是无法进行打洞的。所以为了通信,只能采取最后的手段了,就是转成C/S架构了,STUN会协调TURN进行消息转发。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40741808/article/details/107686105