P2P中的NAT技术

P2P 为 Peer To Peer,顾名思义是对等的端对端通讯而不需要借助第三者。

端对端的能充分的利用两端的网络资源,减少对公共服务器的依赖。但在 IPv4 短缺的今天,有很多设备是在一个内网里向外传输信息的,基本上做不到每台设备拥有独立IP。而普通情况下,在内网的设备很难被主动访问,因此很难直接通讯。P2P的直接通讯需要借助在网关设备上的 “打洞” 来进行。

要解释 “打洞” 就需要从NAT技术讲起。

NAT 介绍

上网搜时,可能看到 NAT 是为了解决 “IPv4地址短缺问题” ,而其实更本质上来说,这是一个路由拥有自洽内网系统的一个必要功能——对于外界来说,传输层IP包的沟通对象是 NAT 网关设备,再由网关转发给对应的子网设备来通讯,这样就能很好的让子网自洽而不用顾及外部的网络环境。

简而言之,NAT 的工作原理是一个 IP、Port 的转换过程,NAT = Network Address Translation。显然它的本质问题,是如何建立并维护起【NAT设备的外网地址 <—> 内网设备地址】的映射关系。

转换关系层级

NAT 转换关系存在许多种策略,它们是一个非此即彼的存在,亦即只会同时生效一种策略。这些转换策略分两个层级。

IP 层的转换

最底层的是只在 IP 层转换。即 NAT网关有多个外网 IP 地址的情况下,将外网 IP 地址跟内网的某用网设备的内网 IP 对应起来。外部对某个外网IP的访问即对应到内网具体的某IP上。

对应关系可以分两种:一种是手动下的静态对应,叫静态NAT(Static NAT);另一种是在外网IP池子里自动动态分配,叫池NAT(Pooled NAT)。

现代的用网设备会远远超出某个 NAT 网关能拥有外网IP,除非有特别的应用场景,否则IP这一层的转换显然不具广泛的适用性,所以不重点讨论。

Port 层的转换

在 Port 层的转换又叫 NAPT,Network Address Port Translation。在这一层的转换已经在 NAT 设备上重用到端口级,亦即一个端口可以转换多条对外的链接。

端口的概念需要关联到具体的运输层协议,比如 UDP、TCP 等,不同的协议需要依赖于 NAT 设备的支持。

在 NAPT 中又根据不同的工作模式,细分了两种不同的类型——对称型(Symmetric NAT)以及非对称性(也叫锥形,Cone NAT)。

同时锥形 NAT 下还会根据对当前端口重用的限制等级分为三种不同的 NAT,完全锥形 NAT(Full cone NAT)、受限NAT(Restricted Cone NAT)和端口受限 NAT(Port restricted cone NAT)。

NAPT 是我们现代网络最常用的 NAT 模式,NAT 设备对 UDP 与 TCP 都有比较好的支持,原理和过程几乎共通。下面展开。

NAPT 的两种大模式

NAPT 按照端口的重用方式,分为两大类——对称型(Symmetric NAT)以及非对称型(也叫锥形,Cone NAT)。

这两类的分类方式的不同,通俗来讲来讲就是 NAT 的同一个内侧设备,对外的不同链接(这个不同包括 IP 与 Port),要不要在NAT设备的外侧新起端口来对应。

如果需要新起端口来对应,意味着每一个新的连接,在外网部分看来,目的地以及源都是全新的。亦即在 NAT 设备的外网侧存在严格的 SourceIP:SourcePort <—> TargetIP:TargetPort 的唯一性,这也是 对称型 名字的由来。反之则是 锥形

一、锥形 NAT(Cone NAT)

锥形的命名其实很形象,指的是 NAT设备内网侧的设备一旦启用某端口进行通讯后,NAT 设备只需要固定开放一个外网侧端口与之对应即可。往后内网设备从这个端口往外的通讯,都固定由外侧的对应的端口转换
这样外网侧看起来就是一个从NAT设备外网端口到外网设备的放射形的结构,因此叫之为锥形
锥形 NAT 也有被称为一对一NAT(one-to-one NAT)。这里的一对一指的是 NAT 设备内网侧设备的 IP:Port 跟其外网侧的 IP:Port 的转换关系。
在这里插入图片描述
出于安全性跟便捷性的平衡考量,这种锥形 NAT 在 NAT 设备的外网侧有三种不同的策略。其严格程度从低到高分别为:全锥型(Full Cone)、受限锥型(Restricted Cone)、端口受限锥型(Port Restricted Cone)。简单来说就是完全不限制、限制外网目标IP、限制外网目标IP+外网目标Port。

1、全锥型(Full Cone)

在这里插入图片描述
如图1示,内网设备的端口 2000,只要跟 NAT 设备的外网侧对应好后(图里没画出来),所有的外网机器、不限制IP、不限制Port,都可以往这里丢信息并被 NAT 设备转发进来。这种模式下,内网设备的某个端口的通讯等于完全暴露在外网中。

2、受限锥型(Restricted Cone)

在这里插入图片描述
在受限锥形模式下,只有内网设备曾经通过某个 NAT 设备外侧端口主动通讯过的外网服务器,才能反过来向内网设备发包。

如图2中,内网设备用 2000 端口通过 NAT 设备的某个端口向 s1 的 3000 端口发送数据,因此 s1 的 2000 端口跟 3000 端口(以及其他任意端口)都可以向内网设备的 2000 端口通讯。

3、端口受限锥型(Port Restricted Cone)

在这里插入图片描述
端口受限锥型比受限锥型对端口也进行了限制,不只是内网设备的主动通讯过的外网IP需要一致,外网服务器与 NAT 设备通讯时的端口也要求是内网设备在主动通讯时的目标端口。

在图3中,s2 的所有端口、s1 的 3000 端口都会被 NAT 设备拒绝。仅有 s1 的 2000 端口是内网设备主动通讯过的对象,报文得以放行。

二、对称型 NAT(Symmetric NAT)

在这里插入图片描述
对称型的 NAT 放弃了 NAT 设备与内网设备端口一对一联系的设定。在对 IP、端口都有限制的前提下,就算是内网设备用同一个端口对不同的目标发起通讯,NAT 设备也会在自己的外网侧开辟新的端口来与之对应。

对称型的 NAT 是最为严格跟安全的策略。同时也是最为死板的。

如上图,即使内网设备用的都是 2000 端口发起对 s1 的通讯,但在 s1 看来,自己的 2000 端口跟 3000 端口,需要通讯的是 NAT 设备上两个不同的端口。

这种策略无疑是比锥形的三种策略都要严格得多,它区分开了每一个独特的链接,像一些超时、流控等策略就可以具体到链接去做了。

NAT 打洞

打洞思路

像这种被 NAT 设备隐藏的设备要通讯,无疑需要一个公共服务器来协助。

注意,由于对称型 NAT 每次发起都会被映射到 NAT 设备的新端口,而不是登录时通知到打洞服务器的端口,同时新端口无法统一预测,所以对称型的 NAT 是难以打洞的只有其中一方是不对端口做限制的策略,而来做被握手的一方才可能可以
不同策略的组合打洞可能性如下:

Peer Peer 能否打洞
全锥型 全锥型
全锥型 受限锥型
全锥型 端口受限锥型
全锥型 对称型
受限锥型 受限锥型
受限锥型 端口受限锥型
受限锥型 对称型
端口受限锥型 端口受限锥型
端口受限锥型 对称型
对称型 对称型

如果两方处于能打洞的 NAT 后方,假设两台需要通讯的设备为 A、B,公共服务器 S,这个打洞过程大概如下:

1)设备A 通过私有协议,携带自己的内网信息、外网信息(此信息可以被 S 自动获知)登录 S。登录后 S 可以对 A 进行测试性发送数据,根据包拒绝与否、端口变化等,来确定设备A 当前的 NAT 类型。此时 S 就有了设备 A 的记录;

2)设备B 重复 1 中的过程,登录 S;

3)设备A 向 S 请求,想与 B 发起直接通讯;

4)S 开始同时向 A、B 发送对方的信息,做打洞准备;

5)A 拿到 B 的外网信息后,对 B 发起了一次通讯,此时 NAT 设备将建立起一个 A 对 B 的口子(session);

6)类似 5,B 同样建立好与通讯 A 的口子;

7)A 或者 B 收到对方的包后,根据上层协议是 TCP 或者是 UDP,A 跟 B 各自做好准备。TCP 会相对复杂一些,因为 A、B 会同时发起一个握手请求,这里面有很多异步的问题。理论上来说只保留一个最先成功的链路即可,实操上会有些许的差异;

8)以上过程可以加入重试来容错。

三种不同的情况

这个过程可以分三种不同的情况来思考其是否成立。

  • 在同一个 NAT 设备下面
    在这里插入图片描述
  • 双方在不同的 NAT 设备下面
    在这里插入图片描述
  • 双方在多层 NAT 设备下面
    在这里插入图片描述

其他

还有其他的细节(比如通讯协议的差异考虑),可具体参考这里的论文:Peer-to-Peer Communication Across Network Address Translators

NAT 一些成熟的打洞方案

上面说了一些简单的理论,下面介绍一下市面已有的一些打洞方案。也许一些方案已经在家里的路由器上集成了(比如UPnP)。感兴趣可以深入了解。

UPnP

UPnP 是一套由 UPnP 论坛颁布的计算机网络协议,官网地址

UPnP 架构允许建立由个人电脑、联网设备和各种无线设备组成的 P2P 网络。当一个新的主机需要连接时,一个 UPnP 设备(比如我家的路由)可以自动配置一个网络地址,宣布其在网络上的子网,并交换设备和服务的描述。

目前,许多互联网网关供应商,如 D-Link、英特尔、Buffalo 科技和 Arescom 都在提供具有 UPnP 功能的设备。

UPnP 中的 NAT 打洞行为被称为互联网网关设备(IGD)协议。然而 UPnP 的一个缺点是,它要求网络中的所有设备都支持UPnP。即使一个设备不符合UPnP标准,我们也不能实现 P2P 通信。

*而且这玩意儿很容易导致家用网络上有bug,比如游戏连不上服务器等等。一般我都是关了它了事。

STUN

这个就没啥好说的了,基本上就是刚刚的思路的企业化实现。
在这里插入图片描述
STUN 一样有上面提到的缺点。对称型的 NAT 很难打通。

Teredo

微软提出的技术。比较有识别点的地方在于,它是 IPv6 时代的产物。

总结

NAT 就介绍完了。作为折腾佬,也许在 IPv6 时代,能保障到自己内网所有的设备都能有一个全局 IP 的时候,也许 NAT 打洞的需求就过去了。

但目前来说 IPv4 还仍然是一个主流的协议(特别是国内)。

了解 NAT 的过程也很有意思, 中间穿插了很多网络相关的知识可供想象。

猜你喜欢

转载自blog.csdn.net/weixin_42445065/article/details/130266309
P2P