NAT的基本原理以及NAT穿透

概述

NAT(“NetworkAddressTranslation”)中文意思是“网络地址转换”,它是一个IETF(InternetEngineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术,如下图所示。因此我们可以认为,NAT在一定程度上,能够有效的解决公网地址不足的问题。
在这里插入图片描述
简单地说,NAT就是在局域网内部网络中使用内部地址,而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口,打个比方就像院子的门一样)处,将内部地址替换成公用地址,从而在外部公网(internet)上正常使用,NAT可以使多台计算机共享Internet连接,这一功能很好地解决了公共 IP地址紧缺的问题。通过这种方法,可以只申请一个合法IP地址,就把整个局域网中的计算机接入Internet中。这时,NAT屏蔽了内部网络,所有内部网计算机对于公共网络来说是不可见的,而内部网计算机用户通常不会意识到NAT的存在。如下图所示。这里提到的内部地址,是指在内部网络中分配给节点的私有IP地址,这个地址只能在内部网络中使用,不能被路由转发。

NAT分类

  • 静态 NAT(Static NAT)

    通过手动设置,使 Internet 客户进行的通信能够映射到某个特定的私有网络地址和端口。如果想让连接在 Internet 上的计算机能够使用某个私有网络上的服务器(如网站服务器)以及应用程序(如游戏),那么静态映射是必需的。静态映射不会从 NAT 转换表中删除。在静态NAT方式中,内部的IP地址与公有IP地址是一种一一对应的映射关系,所以,采用这种方式的前提是,机构能够申请到足够多的全局IP地址。

  • 动态 NAT (Pooled NAT)

    动态地址NAT只是转换IP地址,它为每一个内部的IP地址分配一个临时的外部IP地址,主要应用于拨号,对于频繁的远程联接也可以采用动态NAT。当远程用户联接上之后,动态地址NAT就会分配给他一个IP地址,用户断开时,这个IP地址就会被释放而留待以后使用。
    动态NAT方式适合于 当机构申请到的全局IP地址较少,而内部网络主机较多的情况。内网主机IP与全局IP地址是多对一的关系。当数据包进出内网时,具有NAT功能的设备对IP数据包的处理与静态NAT的一样,只是NAT table表中的记录是动态的,若内网主机在一定时间内没有和外部网络通信,有关它的IP地址映射关系将会被删除,并且会把该全局IP地址分配给新的IP数据包使用,形成新的NAT table映射记录。

  • 网络地址端口转换 NAPT (PortLevel NAT)
    网络地址端口转换NAPT(Network Address Port Translation)则是把内部地址映射到外部网络的一个IP地址的不同端口上。它可以将中小型的网络隐藏在一个合法的IP地址后面。NAPT与 动态地址NAT不同,它将内部连接映射到外部网络中的一个单独的IP地址上,同时在该地址上加上一个由NAT设备选定的端口号。

    1. SNAT (Source NAT ):修改数据包的源地址。源NAT改变第一个数据包的来源地址,它永远会在数据包发送到网络之前完成,数据包伪装就是一具SNAT的例子。

    2. DNAT(Destination NAT):修改数据包的目的地址。Destination NAT刚好与SNAT相反,它是改变第一个数据包的目的地地址,如平衡负载、端口转发和透明代理就是属于DNAT。

    NAT实现方式

    • 全锥NAT(Full Cone NAT)

      一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。任意外部主机都能通过给eAddr:port2发包到达iAddr:port1。

    • 限制性锥NAT(Address-Restricted Cone NAT)

      一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。任意外部主机(hostAddr:any)都能通过给eAddr:port2发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:any。 "any"也就是说端口不受限制。

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

      端口限制性锥NAT与限制性锥NAT类似,只是多了端口号的限制。 一旦一个内部地址(iAddr:port1)映射到外部(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。一个外部主机(hostAddr:port3)能够发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:port3.

    • 对称NAT (Symmetric NAT)

      每一个来自相同内部IP与端口,到一个特定目的地地址和端口的请求,都映射到一个独特的外部IP地址和端口。 同一内部IP与端口发到不同的目的地和端口的信息包,都使用不同的映射。
      只有曾经收到过内部主机数据包的外部主机,才能够把数据包发回
      其中完全锥性NAT 的穿透性最好,对称形NAT的安全性最高。

NAT原理

  • 地址转换

  • 连接跟踪

  • 端口转换

    参考链接:NAT原理

NAT缺陷

  • 不能处理嵌入式IP地址或端口
  • 不能从公网访问内部网络服务
  • 有一些应用程序虽然是用A端口发送数据的,但却要用B端口进行接收,不过NAT设备翻译时却不知道这一点,它仍然建立一条针对A端口的映射,结果对方响应的数据要传给B端口时,NAT设备却找不到相关映射条目而会丢弃数据包。
  • 一些P2P应用在NAT后无法进行
  • NAT设备对数据包进行编辑和修改操作,降低了发送数据的效率;而且由于增加了技术的复杂性,排错也变得困难了。

NAT穿透

NAT 不仅实现地址转换,同时还起到防火墙的作用,隐藏内部网络的拓扑结构,保护内部主机。 NAT 不仅完美地解决了 lP 地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。这样对于外部主机来说,内部主机是不可见的。但是,对于P2P 应用来说,却要求能够建立端到端的连接,所以如何穿透NAT 也是P2P 技术中的一个关键。

UDP打洞

  • 双方都通过UDP与服务器通讯后,网关默认就是做了一个外网IP和端口号 与你内网IP与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网IP。
  • 用户A先通过服务器知道用户B的外网地址与端口
  • 用户A向用户B的外网地址与端口发送消息
  • 在这一次发送中,用户B的网关会拒收这条消息,因为它的映射中并没有这条规则。
  • 但是用户A的网关就会增加了一条允许规则,允许接收从B发送过来的消息
  • 服务器要求用户B发送一个消息到用户A的外网IP与端口号
  • 用户B发送一条消息,这时用户A就可以接收到B的消息,而且网关B也增加了允许规则
  • 由于网关A与网关B都增加了允许规则,所以A与B都可以向对方的外网IP和端口号发送消息。

参考资料:
UDP穿透
NAT打洞

STUN( NAT穿透使用, 实际是NAT内部设备获取外部ip地址的一种协议)

  • old–STUN(RFC3489 )

Simple Traversal of UDP Through NATs,顾名思义,它只支持UDP穿透,它是一个完整的解决方案。

  • == new–STUN(RFC5389)==
    STUN代表Session Traversal Utilities for NAT,新版本中STUN定义为NAT穿透辅助工具,它也不再是一个完整的解决方案。

它允许位于NAT(或多重NAT)后的客户端找出自己的公网址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于 NAT路由器之后的主机之间建立UDP通信

STUN协议的工作流程

获取外部网络地址

stun协议的最简单的工作流程就是获取外部网络地址,这个流程有时被称为“打洞”,简单来说获取绑定地址,流程如下:

  1. client发送stun请求到外部网络的server
  2. 外部网络的server获取到这个请求后,将数据包的实际来源地址填入到response信令中
  3. client解析response信令,获取该设备的外部网络地址

主要原理是,所有NAT只要内部网络的设备使用IP+端口向外部网络的某个设备的IP+端口发送过数据包,那么来自这个外部网络IP+端口的数据包就一定能到达内部网络的设备。

在第二点中外部的server会将数据包的实际来源地址,填入到stun 响应的属性中,这个属性在RFC3489中位mapped address, 而在RFC5389中为xor-mapped address。很多服务器的实现都会同时在这两个属性中将本地地址添加上,进而对终端进行更好的兼容。

维持地址绑定

当内部设备获取到自身的外部网络地址后,此时NAT上的处理就是建立了一个地址绑定关系,但是NAT对于这个地址绑定关系的存在时间具有限制,所以在一段时间后,这个绑定关系会被NAT回收,如果想一直持有这个绑定关系,就需要内部设备不断通过这个地址绑定关系向外部发送数据包。
对于一个stun client来说,这里最简单的处理就是发送stun request,通过stun request就可以不断刷新这个绑定关系(很多文章中称为NAT上的洞)的持续时间。
当然,这里还可以使用stun indiction去进行刷新,这样会更加轻量化,但是使用stun indction将会存在一个,如果NAT上这个绑定关系由于某些原因被重置,这将会导致内部设备无法感知到这一变化,所以交替使用stun request和stun indiction可能是一个更优的选择,不过在webRTC的实现中,一直都使用stun request去刷新绑定关系。

stun client的鉴权流程

stun 协议定义了两套鉴权流程,分别是短期凭证机制和长期凭证机制。这二者实际上都是运用了账号密码这个机制,所不同的是短期凭证机制是通过其他协议传递stun的用户名和密码,这个用户名和密码的有效期的使用期限非常短,可能仅在一次通话中使用。而长期凭证机制是直接获取到的,可以长期使用。

短期凭证机制和长期凭证机制的逻辑实际上都是通过stun协议的附加属性来完成,在鉴权流程中需要用到的属性是MESSAGE-INTEGRITYUSERNAME属性。

关于短期/长期凭证机制

参考博客:
凭证机制

参考博客:
关于STUN原理
STUN信令详解
STUN协议详解

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值