P2P技术详解:P2P中的NAT穿越方案(进阶分析篇)笔记

586 阅读10分钟

NAT和NAPT

NAT(Network Address Translation,网络地址转换),早期的NAT指静态NAT(Basic NAT),它在技术上较简单,仅支持地址转换而并不支持端口映射。需要令每个当前连接对应一个IP地址,因此需要维护一个公网的地址池

明显的缺陷就是:同一时刻只能少量位于NAT后面的机器能够和外部交互(要看NAT有几个外网IP)

而后期的NAT基本都是指网络地址端口转换(NAPT),这种方式支持端口的映射并允许多台主机共享一个公网ip地址,这样即可支持同时多个位于NAT后的主机与外部网络进行交互

支持端口转换的NAT又可以分为两类:

  • 源地址转换(SNAT)
  • 目的地址转换NAT(DNAT)

NAT带来的问题以及P2P通信穿越NAT的方式

NAT带来的问题

  • NAT使IP会话的保持时效变短
  • NAT在实现上将多个内部主机发出的连接复用到同个IP上,这使依赖IP进行主机跟踪的机制都失效了
  • NAT工作机制依赖于修改IP包头的信息,这会妨碍一些安全协议的工作
  • NAT限制了使用一些高层协议(FTP、Quake、SIP)的Peer两端的P2P通信

P2P通信穿越NAT的技术、方法

  • 应用层网关
  • 中间件技术
  • 打洞技术
  • Relay(服务器中转)技术

以下主要记录Ralay(服务器中转)技术

应用层网关

应用层网关(ALG,Application Layer Gateway)是解决NAT对应用层协议无感知的一个最常用方法,已经被NAT设备厂商广泛采用,成为NAT设备的一个必需功能。

在NAT网关检测到新的连接请求时,它会利用带有ALG(Application Layer Gateway)功能的NAT对特定应用层协议进行支持和理解。首先,NAT网关会判断该连接请求是否为已知的应用类型,通常是通过分析连接的传输层端口信息来进行识别的。

如果识别出是已知应用类型的连接请求,NAT网关将会调用相应的功能来对报文的深层内容进行检查。在这个过程中,当发现任何形式表示的IP地址和端口信息时,NAT网关会将这些信息同步转换,并且为这个新连接创建一个附加的转换表项。

这样一来,当报文到达公网侧的目的主机时,应用层协议中携带的信息就会是NAT网关提供的地址和端口。

限制

ALG技术在实现NAT穿越方面,依赖于NAT本身的支持。这种方案存在一定的局限性,主要是因为ALG通常针对特定协议的特定版本进行开发。由于协议本身可能发生变化,以及协议种类的增加,ALG的适应性受到限制。

中间件技术

是一种通过开发通用方法解决NAT穿越问题的努力。AGL技术中NAT网关是这一解决方案的唯一参与者,而中间件技术中客户端会参与网关公网映射信息的维护。UPnP就是这样一种方法,UPnP中文全称为通用即插即用,是一个通用的网络终端与网关的通信协议,具备信息发布和管理控制的能力。

NAT的主要任务是理解客户端的请求,并根据这些请求分配相应的映射转换表。这一过程并不需要NAT去分析客户端的应用层数据。在处理请求时,网关可以为客户动态地添加映射表项

限制

然而,这种方案的实施需要满足一定的条件。首先,网关、内部主机和应用程序都必须支持UPnP(Universal Plug and Play)技术。其次,网络环境必须允许内部主机和NAT网关之间可以直接交换UPnP信令。

打洞技术

Hole Punching技术是工作在运输层的技术,可以屏蔽上层应用层的差异,并且不需要NAT网关特定的支持,因此其通用性比较强,应用性也比较广。

打洞技术的原理相对简单,它主要是在NAT设备上为内网节点建立一条特定的转发映射关系,这个过程就像在NAT上"打一个洞"。为了方便描述,我们将一对IP地址和端口信息的组合称为一个Endpoint。

打洞技术的实现过程可以简化为以下三个步骤:

  • 首先,位于NAT后的节点Peer1需要向外发送数据包。这个操作的目的是让NAT建立内网Endpoint1(IP1PORT1组成,即地址二元组)与外网Endpoint2(由IP2PORT2组成)之间的映射关系。

  • 接下来,将映射后的外网Endpoint2通过某种方式通知给另一个节点Peer2

  • 最后,Peer2向收到的外网Endpoint2发送数据包。此时,NAT会将这些数据包转发给内网的Peer1

NAT行为类型与侦测方法

NAT的行为类型和侦测方法是由STUN(Simple Traversal of UDP Through NATs,首先在RFC3489中定义)协议来描述的

经典STUN定义的 NAT 行为类型是将NAT的Mapping Behavior (映射规则)和Filtering Behavior(过滤规则)统一来归类的,这样对Symmetric NAT(对称式网络地址转换)类型的归类过于笼统,使得许多 NAT 不完全符合由它定义的类型。 后来,RFC3489被废弃并由RFC5389来替代,在RFC5389中,将Mapping Behavior (映射规则)和Filtering Behavior(过滤规则)分开来,定义了3种Mapping Behavior (映射规则)和3种Filtering Behavior(过滤规则),共有9种组合。

对于一个特定的内网源Endpoint1,影响其映射关系的因素:

  • 目的IP和目的端口PORT都无关
  • 目的IP和目的端口PORT都相关
  • 仅仅目的IP相关
  • 仅仅目的PORT相关

NAT打洞过程

“打洞”方式穿越NAT有两种形式:TCP”打洞”和UDP”打洞”。原理上TCP”打洞”与UDP”打洞”没有本质的区别。

然而在实现上,TCP”打洞”的成功率远没UDP”打洞”的成功率高,原因如下:

  • 部分NAT防火墙策略对TCP协议不太友好,不允许来自不明外部的TCP连接。
  • TCP协议本身的问题,如TIME_WAIT状态可能导致同一NAT后面的其他主机发起的连接被误判。
  • TCP协议的实现API,标准的Berkeley sockets API是围绕C/S编程设计的,一个套接字不能既用来监听又用来初始化向外的连接。而TCP打洞需要本地的TCP端口既可以监听外入的连接,又能发起多个向外的连接。

Relay服务器中转技术

进行P2P穿透是否成功与NAT的行为和防火墙策略有很大的关系,因此就算是一个P2P友好NAT也很难保证100%穿透成功。

P2P穿透的关键部分包括relay,主要由TURN协议描述。它补充了STUN协议,涉及RFC5766(UDP relay)、RFC6062(TCP relay for IPV4)和RFC6156(IPV6 relay)。

在TURN中,客户端向turn server请求分配(allocation),获得一个relay地址。该地址有有效期,可通过refresh request延长。创建权限后,客户端可经turn server中转数据给对端。未授权通信会被丢弃。

UDP协议的Relay

RFC5766(UDP relay)有两种方式:第一种是Send and Data methods,第二种是channels

Send and Data methods

P2P穿透中,TURN协议补充STUN,处理NAT限制。核心步骤如下:

  1. Client请求分配:客户端向turn server发送Allocate request,包含属性如事务ID、期望的有效期和未来数据传输的协议。
  2. Turn Server响应错误:如果授权失败,turn server回复Allocate error response,提示需用户验证,提供REALM和NONCE。
  3. Client提供验证信息:客户端重新发送Allocate request,附带用户名、密码等信息。
  4. Turn Server分配地址:验证通过后,turn server响应Allocate success response,提供relay地址和映射地址。
  5. Client创建权限:客户端发送CreatePermission request,为peer创建权限。
  6. Turn Server确认权限创建turn server接受请求,响应CreatePermission success resp
  7. Client发送数据:客户端用Send indication发送数据给turn server,由它relaypeer
  8. Peer响应数据peer收到数据后,响应数据给turn server
  9. Turn Server转发数据turn server检查权限后,将数据封装成Data indication发送给client

注意:每个allocation有有效期,需要及时刷新延长。

channels

在P2P穿透中,TURN协议处理NAT限制。除Send and Data methods外,还有Channel Binding方式:

1-6的交互过程与Send and Data methods相同

  1. Client绑定通道:发ChannelBind request,指定channel IDpeer地址。
  2. Turn Server确认绑定:响应ChannelBind success response
  3. Client发送数据:通过ChannelData发送数据,只需channel ID
  4. Turn Server转发数据:检查channel绑定后,将数据UDP发给peer
  5. Peer响应数据:回复数据给turn server
  6. Turn Server处理响应:检查client是否有权限和channel绑定,再通过ChannelDataData indication方式转发数据给client

Channel Binding减少了数据量,提高了效率。

TCP协议的Relay

RFC6062(TCP relay for IPV4),主要有两种情况下的relay:第一种是Client to peer 第二种是Client to client

  1. Client to peer:这种情形下,一个客户端(Client)想要与另一个位于NAT后面的对等端(Peer)进行通信。为了实现这一点,通常会有一个公网上的Relay服务器介入。客户端首先与Relay服务器建立一个连接,然后通过Relay服务器转发数据到目标对等端。在此过程中,Relay服务器起到了中转站的作用,使得即使对等端位于NAT之后,仍然能够接收到来自客户端的数据。
  2. Client to client:在这种场景下,两个客户端都试图通过NAT与对方建立直接的P2P连接。由于NAT的限制,直接通信可能不总是可行。在这种情况下,两个客户端各自与Relay服务器建立连接,并通过Relay服务器来交换数据。这样,Relay服务器就扮演了中介的角色,帮助两个客户端绕过NAT的限制,实现间接的点对点通信。

在这两种情况下,NAT设备的类型和配置可能会影响穿越NAT的成功与否。例如,全克隆(Full Cone)类型的NAT会将所有来自相同内部IP地址和端口的请求映射到相同的外部IP地址和端口,这有助于简化穿越过程。

未完待续...

原文链接:P2P技术详解(一):NAT详解——详细原理、P2P简介