NAT穿透

 

  因特网是有无数网络组成的,它们被最基础的transport protocols协议绑定在一起共用地址空间。

  当数据在网络直接流转,一个叫做网络地址转换的过程经常出现。网络地址转换将一个地址从一个地址空间映射到另一个地址空间。

  NAT允许很多设备共用一个公共地址,这也是IPv4协议到现在还能正常工作的基础,否则根据它32位的地址空间是不足以满足现在的网络设备需求的。

  例如,当我连接到我们家的wifi,我的计算机获得了一个10.0.1.15IPv4地址。它属于为私有网络保留的内部网络地址。当我向外部公共网络地址建立一个连接,路由器会使用它自己的公共网络地址代替我的内部网络地址。当数据从其他地方传入时,路由器会将地址转换回内部地址。

  然而NAT对外部连接是透明的,监听连入的连接需要一些配置。路由器在单一的公共IP地址上进行监听,但是内部网络中任何数量的计算机都能处理请求。为了服务这些请求,你的路由器必须为特定的计算机配置特定的发送通道,通常是通过一个或多个公共IP的TCP或UDP端口映射到一个内部网络地址。

  虽然通常可能要手工配置路由器,但是不是每个想运行p2p应用节点或其他网络服务的人有能力这么做。

  我们想让libp2p应用运行在任何地方,不只是数据中心或其他有固定公共网络IP地址的计算机上。为了实现这个目标,在现今的libp2p中已有几种主流的网络穿透方法。

自动路由配置

  许多路由器都为端口转发提供自动路由配置,最常用的是 UPnP 和 nat-pmp.

  如果你的路由器支持这两种协议中的一种,libp2p就会尝试自动配置端口映射,使得它能够监听连入请求。如果被网络和libp2p实现支持,这通常是最简单的选项。

  Libp2p实现支持多种自动NAT配置。详细请看current implementation status

Hole-punching (STUN)

  当一个内部网络的计算机拨出并与有公共地址的计算机建立连接,路由器会为这个连接映射一个公共端口到内部网络IP地址。在一些情况下,你的路由器会从这个公共端口接收接入的连接请求并将该链接路由到相应的内部IP地址。

  在使用支持IP的传输时,libp2p会尝试利用这个行为,使用一个名为SO_REUSEPORT的套接字选项,通过使用相同的端口进行拨号和监听。

  如果我们的节点拥有良好的网络环境,它们是可以建立一个外部连接并获得一个公共网络可以联系的监听端口,但是它们可能永远也不知道这个事情。不幸运的是,现在没有一个可行的方法为发出拨号的程序提供发现哪个端口被分配给了自己这个连接。

  但是,一个外部节点可以告诉我们它们观察到了什么地址。我们能够获得这个地址,并将其在我们的网络中( peer routing network)广播给其它节点,使它们知道从哪里发现我们。

  将它们观察到的地址通知给其它节点的这个基本前提是 STUN(是NAT的会话穿透实用工具)的基础,STUN是描述用于发现公开可达IP地址和端口组合的客户端/服务器协议。

  Libp2p其中的一个核心协议是认证协议identify protocol,它允许一个节点向另一个节点询问认证信息。当节点发送公钥和其他的一些有用信息,这个节点就会被其他节点进行身份认证,其中包括这个节点所观察到的地址集合。

  外部节点发现机制与STUN扮演相同角色,但是不需要STUN 服务器集合。

  身份认证协议允许一些对等节点在NAT之间进行通讯,否则它们无法穿过NAT。

AutoNAT

  虽然上面描述的身份认证协议可以让对等节点相互之间通知它们观察到的网络地址,但是并不是所有的网络都允许通过它们拨号出去的端口接收连入连接。

  再次,其他节点可以帮助我们观察我们自己的情况,这个过程是通过其他节点尝试拨号我们观察到的地址实现。如果这个过程是成功的,我们也可以依靠其他可以拨号我们的节点并且广播我们的监听地址。

  Libp2p的一个叫做AutoNAT 的协议可以让节点从通过提供AutoNAT服务的节点发送回拨请求。

Circuit Relay (TURN)

  在一些情况下,对等节点不能够以公开的方式遍历它们的NAT。

  Libp2p提供了Circuit Relay protocol协议,使得对等节点能够通过中间帮助节点进行间接通讯。

  这里提供了与在其他系统中使用的 TURN protocol协议相似的功能。

posted on 2021-01-06 13:36  冷月_孤星  阅读(521)  评论(0编辑  收藏  举报