跳转至

NAT类型

因为下面的章节中提到的 ZeroTier 是基于 P2P 打洞方式减少延迟优化传输体验的,所以必定会涉及到 NAT 类型的基础知识,其实 NAT 类型我们之前大概率应该也接触过,一些联机游戏也经常涉及到这块,NAT 类型很差的话,会导致联机的延迟很高,没有游戏体验。

NAT 基础概念

NAT(Network Address Translation 网络地址转换)是一种网络技术,可以将内部网络中的 IP 地址转换为公共 IP 地址,以便在 Internet 上进行通信。设计之初的目的是为了节省 IP 地址,避免出现 IPv4 地址池耗尽的情况,同时也让一些家用设备的更加安全,减少了直接被外部攻击的风险。但是缺点也比较明显,一些联机游戏或者涉及到 P2P 打洞的方案中,NAT 越复杂,会导致我们的延迟或者下载速度越差,导致一些联机游戏没法愉快的玩耍。

NAT 类型标准

标准一

  • NAT type 1 - Open

    开放式 NAT 类型,无任何限制,所有设备都可以自由发送和接收数据,并且没有防火墙。还可以轻松与其他 NAT 类型设备连接交互。

  • NAT type 2 - Moderate

    中等适度式 NAT 类型,安全性要高一点,仅开发几个端口,依然可以使用防火墙来保护我们的设备安全,但同时也会略微降低我们设备的互联网速度。

  • NAT type 3 - Strict

    严格式 NAT 类型,这是最严格的 NAT 类型,安全性最高,但也是上网体验最差的一种类型,会减慢我们的互联网访问速度,同时也可能增加游戏的延时。

标准二

  • Static NAT

    静态 NAT:静将内部网络中的 IP 地址一一映射到公共 IP 地址上。这种方式主要用于服务器网络中,以便让外部网络访问内部网络中的服务。

  • Dynamic NAT

    动态 NAT:动态 NAT 将内部网络中的 IP 地址映射到公共 IP 地址池中的地址上。这种方式主要用于客户端网络中,以便让内部网络中的客户端访问 Internet。

  • Overloading / Port Address Translation (PAT)

    隐藏 NAT:是一种特殊的 NAT 方式,它将内部网络中的 IP 地址映射到公共 IP 地址池中的地址上,并将内部网络中的地址隐藏起来。这种方式主要用于网络安全中,可以隐藏内部网络的 IP 地址,提高安全性。

    PAT 是一种特殊的动态 NAT,它将内部网络中的 IP 地址和端口号映射到公共 IP 地址池中的地址上。这种方式也是一种隐藏 NAT 的实现方式,用来解决内部网络中地址资源不足的问题。

标准三

  • Full-cone NAT

    全锥形 NAT:对于内部网络中的任意主机都可以直接连接外部网络中的任意主机。优点是连接简单,可以直接连接任意主机,缺点是地址资源浪费,容易受到攻击。

  • Restricted-cone NAT

    限制锥形 NAT:对于内部网络中的主机只能连接外部网络中已经建立连接的主机。优点是提高安全性,缺点是需要预先建立连接,连接数量有限。

  • Port-restricted cone NAT

    端口限制锥形 NAT:与限制锥形 NAT 类似,但是限制是针对端口号而不是 IP 地址。优点是提高安全性,缺点是端口资源浪费,需要预先建立连接。

  • Symmetric NAT

    对称 NAT:对于内部网络中的主机来说,每次连接都需要重新映射。优点是提高安全性,缺点是连接繁琐,地址资源浪费。

检测 NAT 类型

  • Windows Xbox 主机小助手

Windows 下测试 NAT 类型的方法比较多,最简单的是应用商店里面下载 Xbox 主机小助手,然后在设置里面的网络部分检测 NAT 类型,可以看出 Xbox 的 NAT 类型的检测标准使用的是我们本文上面的「标准一」:

Windows 下测试当前网络的 NAT 类型(STUN)的小工具,测试起来也十分简单方便,可以很直观的了解我们的 NAT 类型,使用的是 RFC 3489 标准,也就是我们本文上面的「标准三」:

  • Pyton 包 pynat
Bash
# 安装 python3 的 pip 包管理工具
apt instll python3-pip

# 安装 pynat
pip install pynat

# 检测当前 NAT 类型
pynat

国光小课堂:RFC 3489 是什么,和 NAT 以及 STUN 有什么关系?

RFC 3489 是由网络工程任务组 (Network Working Group) 发布的一篇文档,它定义了 STUN 协议的标准。该协议是一种简单的基于 UCP 的协议,用于确定终端主机的公共 IP 地址和端口号。

STUN 协议是在 RFC 3489 中定义的,它是一种网络协议,用于穿越 NAT 防火墙和防网络地址转换 (NAT) 设备。STUN 用于确定终端主机的公共 IP 地址和端口号,并将其告知终端主机,以便它可以与其他终端主机进行通信。

NAT 是网络地址转换的缩写,它是一种网络技术,用于在内部网络和外部网络之间建立一个隔离层,以保护内部网络免受外部网络的攻击。STUN 协议是为了解决 NAT 对网络通信的影响而开发的。

总结:RFC 3489 是 STUN 协议标准定义文档,它描述了如何使用 STUN 协议确定终端主机的公共 IP 地址和端口号,以便它能够穿越 NAT 防火墙和进行网络通信。这些信息可以用于帮助终端主机与其他终端主机建立连接,或者在跨网络的视频通话或即时通讯应用中发现和解决问题。

改善 NAT 类型

如上图所见,我的 PVE 工作站所在的运营商网络环境的 NAT 类型为 Symmetric NAT,是最严格的一种 NAT 类型,它会为每个外部连接分配一个不同的内部地址,这会导致网络穿透延迟增加。

要改善 NAT 类型,理论上我们可以尝试以下几种方法(要根据我们的实际网络环境来选择最合适的方法):

  1. 尝试使用公共 IP 地址:如果您的设备有公共 IP 地址,就可以不使用 NAT 做网络转换了。
  2. 使用端口转发:端口转发可以将外部流量转发到内部网络中的某个特定端口。
  3. 使用 VPN:使用 VPN 可以将您的网络连接到另一个网络,从而避免 NAT。
  4. 使用第三方服务:有许多第三方服务可以帮助您穿透 NAT。例如:Hole punch, UPnP Teredo
  5. 使用 Zerotier 的路由器支持的模式:Zerotier 支持使用路由器的 NAT-PMP 或 UPnP 来设置端口转发。

上面是理论的解决方法,在实际生活中我们大多数会采用下面的解决方法来改善我们的 NAT 类型:

  • 光猫开启桥接模式,使用路由器进行拨号

路由器直接拨号即可获得外网 IP 地址,这样就少了一层 NAT,下图是小米路由器开启拨号的上网信息概览,可以直接看到获取了外网的 IP 地址:

  • 路由器开启 UPnP 通用即插即用功能

UPnP 或通用即插即用是一种协议集,允许设备连接和应用程序(主要是游戏)自动转发端口。虽然这样会极大的改善我们的 NAT 类型,但是自动端口转发也会带来一些潜在的安全风险。

  • Windows 上打开网络发现

这种方法可以比作为 UPnP 的计算机端的版本,提高了互联网速度以及设备在 Windows 上轻松找到彼此的能力,在控制面板里面找到「高级共享设置」勾选「启用网络发现」即可:

  • 路由器开启 DMZ 功能

路由器的DMZ(隔离区)是指单个用户完全暴露在互联网上,非常简单粗暴高效,不过也会带来一些被攻击的安全风险,小米路由器的「高级设置」-「端口转发」最下面可以找到 DMZ 功能,填入我们想要改善 NAT 类型的设备的 IP 地址即可:

这样相当于内网中的 192.168.31.206 设备完全端口一对一暴露在我们的公网 IP 上面:


最后更新: 2023-03-06