本文章永久分享链接: https://tflow.top/NAT

对NAT行为模式的分类经历了2个阶段:RFC3489与RFC5780

RFC3489使用以下术语来表示NAT的不同变体。

  • NAT1:完全锥形-Full Cone
    • 描述:一旦内网设备(比如你的电脑)通过一个内部端口(例如 50000)与外部任何一个IP和端口通信,路由器就会打开一个对应的公网端口。之后,互联网上的任何设备,无论它是不是你之前通信过的,都可以通过这个公网端口主动连接回你的内网设备。接回你的内网设备。
    • 特点:最宽松,连接性最好,但安全性最低。一般家庭网络不会默认是这种类型。
  • NAT2:限制锥形-Restricted Cone
    • 描述:内网设备与一个外部IP(例如游戏服务器 1.2.3.4)通信后,路由器打开一个公网端口。之后,只有这个特定的外部IP(1.2.3.4) 可以通过这个端口主动连接回你的设备,其他IP不行。
    • 特点:在连接性和安全性之间取得了很好的平衡。这是联机游戏和大多数P2P应用所追求的“最佳”状态。
  • NAT3:端口限制锥形-Port Restricted Cone
    • 描述:比NAT2更严格。内网设备与一个外部IP的特定端口通信后,路由器打开一个公网端口。之后,只有那个特定外部IP的特定端口才能连接回来。
    • 特点:限制更多,可能导致部分联机游戏困难或无法担任主机。
  • NAT4:对称-Symmetric
    • 描述:最严格的类型。内网设备访问每一个不同的外部目标(IP:端口),路由器都会为其分配一个全新的、不同的公网端口
    • 问题:假设你的游戏客户端同时连接游戏服务器和另一个玩家的主机,路由器会开出两个不同的公网端口。对方玩家主机看到你的IP和端口,与游戏服务器看到的不一样,导致直接P2P连接失败。这就是为什么对称型NAT联机体验最差。

RFC 5780对NAT行为模式进行了细分,定义了单独的NAT行为,主要包括:NAT映射行为NAT过滤行为

为了解释RFC 3489 和 RFC 5780 中定义的NAT类型之间有什么区别,我们首先要熟知STUNNAT映射行为NAT过滤行为

STUN是什么

STUN 是一种网络协议,它的核心使命是帮助两个位于不同内部网络(比如你家的Wi-Fi和你朋友家的Wi-Fi)的设备,发现它们之间是否存在网络地址转换(NAT) 设备(通常就是我们常说的“路由器”),并找出各自的公共互联网地址和端口。这个过程是为两个设备之间建立直接的点对点(P2P)通信 铺平道路的关键第一步,广泛应用于视频会议、在线游戏、文件传输等场景。

简单来说,STUN 就像一个中间人引路人。当两个设备想直接“打电话”时,它们各自可能躲在“公司前台”(NAT)后面,不知道对方的公开联系方式。STUN 服务器的作用就是告诉每个设备:“从公共互联网上看,你的联系地址是这个!”,这样它们才能尝试直接联系。

为什么我们需要 STUN?

要理解 STUN 的价值,我们必须先了解 NAT(网络地址转换)

  • NAT 是什么? 由于全球 IPv4 地址短缺,我们家庭或办公室的网络通常只拥有一个公共 IP 地址。而内部设备(如您的手机、电脑)使用的是私有 IP 地址(如 192.168.1.10)。NAT 设备(路由器)的任务就是将内部私有地址转换成唯一的公共地址,从而实现所有设备共享一个IP上网。
  • NAT 带来的问题: NAT 在保护内部网络的同时,也成了一堵“墙”。外部设备无法主动向墙内的设备发起连接,因为它不知道墙内设备的“门牌号”(内部IP和端口)是什么。这对于服务器来说是好事,但对于需要直接、双向通信的 P2P 应用(如微信视频通话)就成了大问题。

STUN 就是来解决这个“麻烦”的。 它通过一个简单而巧妙的方法,帮助设备发现这堵“墙”的存在,并找到墙上为它打开的“那扇窗”(公共IP和端口)。

STUN 是如何工作的?

STUN 协议的工作流程非常直观,可以概括为“询问-回答”模式:

  • 发起询问: 位于 NAT 后面的客户端(比如您的视频通话软件)向一个部署在公共互联网上的 STUN 服务器 发送一个请求:“你好,请告诉我,从你的角度看,我的地址和端口是什么?”
  • 服务器回答: STUN 服务器收到请求后,会查看这个请求包的来源 IP 地址和端口。然后它回复客户端:“我从公共互联网上看到,你的地址是 公网IP:端口号。”
  • 客户端知晓: 客户端通过这个回复,就知道了自己的公共映射地址。它可以将这个地址告诉给想要通信的对端设备。
  • 建立连接: 对端设备拿到这个公共地址后,就可以尝试向这个地址发送数据包。数据包会经过 NAT,由 NAT 设备根据其内部映射表,将数据包转发给最初发起请求的内部客户端。

这样一来,两个原本躲在各自 NAT 后面的设备,就通过 STUN 服务器的帮助,成功地“接上了头”。

需要注意的是: STUN 并不能解决所有 NAT 穿越问题。对于一些对称型 NAT 或严格的企业级防火墙,STUN 可能失效。这时就需要更复杂的协议,如 TURN 或 ICE 来协同工作(即中继)。

STUN 协议的演进

STUN 协议本身也在不断发展,以应对现实中复杂多样的 NAT 设备。

  • RFC 3489(2003年,经典 STUN):
    • 全称: Simple Traversal of UDP through NATs
    • 核心思想: 定义了一套算法,试图将 NAT 设备精确地分类为完全锥形、受限锥形、端口受限锥形、对称型 四种类型。客户端通过一系列测试来确定 NAT 类型,从而决定采用何种穿越策略。
    • 问题: 现实中的 NAT 设备行为千差万别,并不完全符合这四种理想模型,导致经典 STUN 的算法在很多情况下不可靠。
  • RFC 5389(2008年,现代 STUN):
    • 全称: Session Traversal Utilities for NAT
    • 名称微调: 从 “Simple” 变为 “Session”,强调了其对“会话”穿越的实用性。
    • 功能简化: 不再试图对 NAT 进行复杂的分类。它的核心任务回归到最基础、最可靠的功能:获取客户端的公共 IP 地址和端口(即 Binding Discovery)。
    • 协议扩展: 增加了新的属性和机制,使其更具灵活性和安全性。
  • RFC 5780(2010年,实验性):
    • 在 RFC 5389 的基础上,新增了 NAT 行为发现 功能。它允许客户端探测 NAT 在分配端口时的行为模式,但这部分属于实验性特性,并非所有客户端和服务器都实现。
  • RFC 8489(2020年,STUN 的演进与精简):
    • 定位: 此 RFC 正式废弃并取代了 RFC 5389,成为当前 STUN 协议的权威标准文档。它并非对协议进行根本性变革,而是在保持向后兼容的前提下,进行澄清、精简和增强。
    • 协议澄清与精简: 删除了 RFC 5389 中一些已过时或未被广泛使用的部分(如旧式指纹机制),使协议规范更加清晰、精简。
    • 安全性强化: 进一步明确了协议的安全考虑,鼓励在可能的情况下使用 TLS 或 DTLS 作为传输层,以提供更好的通信安全保障。
    • 传输协议正式化: 更明确地支持在 TCP 和 TLS-over-TCP 上运行 STUN,而不仅仅局限于 UDP,以适应更多样的网络环境。
    • 算法修正: 对 RFC 5389 中的一些算法描述进行了修正和优化,使其更严谨、更易于实现。

RFC 8489 代表了 STUN 协议的成熟与稳定。它巩固了 STUN 作为一项基础性 NAT 穿透工具的地位——专注且高效地完成“获取公网映射地址”这一核心任务,并为 TURN、ICE 等更上层的 NAT 穿越框架提供可靠支持。

今天我们所谈论的 STUN,通常指的就是 RFC 8489 定义的版本。

NAT映射行为

NAT映射行为的定义:当内部端点通过NAT打开传出会话时,NAT会为会话分配外部IP地址和端口号,以便NAT可以接收、转换和转发外部端点的后续响应报文。这是内部IP地址与端口和外部IP与端口元组之间的映射。它建立了在会话持续期间NAT将要执行的转换。

简单来说,针对从内部端点发出的报文,经过NAT后,在NAT设备上如何为其分配映射后的IP和端口。

有三种映射行为:

  • 端点无关映射(Endpoint-Independent Mapping):NAT对从相同的内部IP地址和端口发送到任何外部IP地址和端口的后续报文,都复用之前的端口映射。该行为对应于旧的行为模式“完全锥形”。
  • 地址相关映射(Address-Dependent Mapping):NAT对从相同的内部IP地址和端口发送到相同的外部IP地址的后续报文复用端口映射,而不考虑外部端口。当外部IP地址改变时,映射也随之改变。该行为对应于旧的行为模式“限制锥形”。
  • 地址和端口相关映射(Address and Port-Dependent Mapping):当映射仍处于活动状态时,NAT会对从相同的内部IP地址和端口发送到相同的外部IP地址和端口的后续报文重用端口映射。当外部IP地址或端口之中的任何一个发生变化,映射也随之改变。该行为对应于旧的行为模式“端口限制锥形”

NAT过滤行为

NAT过滤行为的定义:NAT使用什么标准来过滤来自特定外部端点的报文。

有三种过滤行为:

  • 端点无关过滤(Endpoint-Independent Filtering):从外部到达的报文,只要其目的IP地址和端口匹配NAT上现有的映射,则都会被NAT转发,无论报文的源IP地址和端口是什么。换句话说,只要内部端点在NAT上建立了映射,所有外部端点都可以使用该映射给内部端点发送报文。该行为对应于旧的行为模式“完全锥形”。
  • 地址相关过滤(Address-Dependent Filtering):从外部到达的报文,只要其目的IP地址和端口匹配NAT上现有的映射,且源IP地址与该映射匹配,则都会被NAT转发,无论报文的端口是什么。换句话说,内部端点在NAT上建立了映射后,只有特定的外部端点可以使用该映射给内部端点发送报文。该行为对应于旧的行为模式“限制锥形”。
  • 地址和端口相关过滤(Address and Port-Dependent Filtering):从外部到达的报文,只有其目的IP地址和端口匹配NAT上现有的映射,且源IP地址和源端口与该映射匹配,才会被NAT转发。换句话说,内部端点在NAT上建立了映射后,只有特定的外部端点使用特定端口,才可以使用该映射给内部端点发送报文。该行为对应于旧的行为模式“端口限制锥形”。

新旧两种NAT行为模式的对比

旧NAT行为模式新NAT行为模式
完全锥形NAT1端点无关映射+端点无关过滤
限制锥形NAT2端点无关映射+地址相关过滤
端口限制锥形NAT3端点无关映射+地址和端口相关过滤
对称NAT4地址和端口相关映射+地址和端口相关过滤

NAT映射行为有3种,NAT过滤行为也有3种,完整组合有9种,上面只列出了4种,剩余5种哪里去了?

首先需要理解一点,映射行为比过滤行为更严格是没有意义的。因为更严格的映射需要占用更多的资源,而宽松的过滤行为并没有提升安全性。所以,我们可以排除其他的5种组合。

接下来可以阅读?