穿透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种不同的类型

  • 完全透明NAT(Full Cone NAT)

这种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)

  • 受限NAT(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)

  • 端口受限NAT(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

STUN(Simple Traversal of UDP over NATs,NAT 的UDP简单穿越)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。该协议由RFC 3489定义。

STUN,是为了实现透明的穿透NAT,而定义的一套协议。它使本地的内网的机器,具有取得,能够得知它的NAT网关的IP,NAT类型的能力。

基本思想

在私网内部安装一个STUN client,在公网上安装一个STUN Server,STUN协议定义了一些消息格式,大体上分成Request/Response,client向server发送 request,server发送response给client。如何检测STUN client是否在NAT后面呢?原理很简单,Server在收到client的UDP包以后,Server将接收到该包的地址和端口利用udp传回来给 client,client把这些地址和端口与本机的ip地址和端口进行比较,如果不同,说明在NAT后面,否则就位于NAT前面。为了检测不同类型的 NAT,STUN协议定义了一些消息属性,要求Server有不同的动作,比如发送响应的时候使用不同的IP地址和端口,或者改变端口等等。STUN协议 对NAT可能有效,但是对防火墙就无能为力了,因为防火墙可能不会打开UDP端口。

STUN Server主要做了两件事:
  • 接受客户端的请求,并且把客户端的公网IP、Port封装到ICE Candidate中。
  • 通过一个复杂的机制,得到客户端的NAT类型。
TURN Server

TURN(Traversal Using Relay NAT),TURN是STUN协议的扩展,在实际应用中他也可以充当STUN的角色;如果一个位于NAT后面的设备想要和另外一个位于NAT后面的设备建立通信,当采用UDP打洞技术不能改实现的时候就必须要一台中间服务器扮演数据包转发的角色,这台TURN服务器需要拥有公网的IP地址

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进行消息转发。
    在这里插入图片描述

各种网络环境下的P2P通信解决方法:

  1. 如果通信双方在同一个局域网内,这种情况下可以不借助任何外力直接通过内网地址通信即可;

  2. 如果通信双方都在有独立的公网地址,这种情况下当然可以不借助任何外力直接通信即可;

  3. 如果通信双方一方拥有独立的公网地址另一方在NAT后面,那么可以由位于NAT后面的一方主动发起通信请求;

  4. 如果通信双方都位于NAT后面,且双方的NAT类型都是cone NAT,那么可以通过一个STUN服务器发现自己的NAT类型以及内网和外网传输地址映射信息,然后通过Signaling(信令服务器,实现了SIP协议的主机)交换彼此的NAT类型及内网和外网传输地址映射信息,然后通过UDP打洞的方式建立通信连接;

  5. 如果通信双方有一方的NAT类型是Symmetric NAT,则无法直接建立P2P连接,这个时候就需要借助TURN(Traversal Using Relay NAT)即转发服务器来实现间接通信。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值