RFC3489(STUN),已过时
RFC3489(STUN)简介
RFC3489(Session Traversal Utilities for NAT,早期称为 Simple Traversal of UDP Through NAT)是最初定义的 STUN 协议,用于帮助客户端在有 NAT(网络地址转换)或防火墙的网络环境中,探测自身在公网上所"呈现"出来的 IP 地址和端口,并推断出 NAT 的类型,从而实现点对点通信(尤其是 UDP 通信)的打洞与穿透。
自 RFC3489 发布后,IETF 又在其基础上进行了修订并发布了 RFC5389,定义了更为通用的 STUN(Session Traversal Utilities for NAT)。但如果我们关注的是 RFC3489 的检测流程,以下内容将对其做一个较为完整的介绍。
RFC3489 检测流程概述
RFC3489 规定了一个通过发送多个 STUN Binding Request 到 STUN 服务器(一般包含至少两个地址或端口)来判断 NAT 类型的流程。它主要基于以下假设:
- 服务器可同时在两个不同地址或端口上侦听(通常称为 Server Reflexive Transport Address #1 和 Server Reflexive Transport Address #2)。
- 客户端可以根据 STUN 服务器返回的结果(Binding Response)来判断自己"看到"的外部 IP 地址及端口,以及基于对不同测试行为结果的分析,推断 NAT 的行为模式。
注意:随着互联网的发展和 NAT 技术的多样化,RFC3489 中的 NAT 类型检测算法在实际环境中并不总是准确;后来才有了更完善的 RFC5389 / ICE(Interactive Connectivity Establishment)等方案。不过理解 RFC3489 的经典检测流程,对于理解 NAT 和 STUN 依然有帮助。
关键概念
- Mapped Address
客户端从 STUN 服务器收到的 MAPPED-ADDRESS 属性(在 Binding Response 中),表示服务器看到的源 IP 与端口,即"公网上"映射出的地址。 - Changed Address
STUN 服务器在响应中可能会携带 CHANGED-ADDRESS 属性,用于指示另一个可用于测试的 STUN 服务器地址或端口(RFC3489 中常常是同一物理服务器上的另一个端口或 IP)。 - NAT 类型
RFC3489 按照不同的 NAT 行为,将 NAT 分为以下几类:
1. Full Cone NAT
2. Restricted Cone NAT
3. Port Restricted Cone NAT
4. Symmetric NAT
以及在无 NAT 的情况即"Open Internet"。
RFC3489 检测流程详解
下文给出了经典的 RFC3489 检测流程示例。实际使用中,客户端需要实现一个简单的"状态机",根据不同测试步骤获得的结果来判断 NAT 类型。
步骤 1: 基础测试 I (Test I)
- 客户端 → 服务器(IP1:PORT1)
1. 客户端向 STUN 服务器(第一个地址/端口,记为 IP1:PORT1)发送一个 Binding Request,请求返回自身的外部映射地址。
- 服务器响应
1. 服务器收到请求后,将客户端源地址作为 MAPPED-ADDRESS 写入 Binding Response 中。
2. 同时在 Binding Response 中携带 CHANGED-ADDRESS,即服务器可用来进行后续测试的"备用地址/端口" (IP2:PORT2)。
- 客户端处理响应
1. 若客户端收到了正确的响应,则可以在返回的消息里读取 MAPPED-ADDRESS。假设该地址为 MappedAddr1。
2. 判断 MappedAddr1与客户端自身的本地绑定地址是否相同:
- 如果相同,说明客户端可能不在 NAT 后(或在一个 Full Cone NAT 中)。继续进行下一步测试以确认具体类型。
- 如果不同,说明客户端在 NAT 后,需要进一步测试确定 NAT 种类。
步骤 2: 基础测试 II (Test II)
- 客户端 → 服务器(IP1:PORT1),但在请求中指定 CHANGE-REQUEST
1. 客户端这次仍然向 IP1:PORT1 发送 Binding Request,但是在 STUN 消息的属性中带上 CHANGE-REQUEST,要求服务器使用与之前不同的地址和端口(即 IP2:PORT2)来发送响应。
- 服务器行为
1. 如果服务器实现了 RFC3489,则会检查 CHANGE-REQUEST 属性,如果属性中指定要"Change IP 和 Change Port",那么服务器就会从 IP2:PORT2 向客户端发送响应。
- 客户端的结果判断
1. 如果客户端 能收到 服务器从 IP2:PORT2 发来的响应,则意味着客户端的 NAT 不会阻止来自不同地址和端口的 UDP 数据包通过。这通常表明客户端所在网络是 Open Internet 或 Full Cone NAT。
2. 如果客户端 收不到 响应,则通常意味着客户端所在的 NAT 会阻止来自不同 IP/端口的响应包,这一现象多与 Symmetric NAT 或者 (Port) Restricted Cone NAT 类型相匹配。为了区分,还需要下一步测试。
步骤 3: 备用地址测试(Test III)
- 客户端 → 服务器(IP2:PORT2)
1. 这次,客户端直接向服务器的另一个地址和端口 IP2:PORT2(即 CHANGED-ADDRESS)发送 Binding Request。
- 服务器响应
1. 服务器收到请求后,会返回客户端的 MAPPED-ADDRESS,记为 MappedAddr2。
- 比较 MappedAddr1 与 MappedAddr2
1. 如果 MappedAddr1 与 MappedAddr2 不同(即,分别是不同的外部端口或 IP),那么通常可以判定为 Symmetric NAT。因为 Symmetric NAT 的映射端口取决于目的地址/端口,对不同目标地址时会出现不同的外部端口。
2. 如果 MappedAddr1 与 MappedAddr2 相同,则说明 NAT 在面对不同的服务器地址时依旧使用同一个外部映射,即不是 Symmetric NAT。结合之前的结果,可以判断是 Restricted Cone NAT 或 Port Restricted Cone NAT。
流程图
常见结果与 NAT 类型判定
以下是根据上述三个测试的可能结果,结合 RFC3489 给出的 NAT 类型划分示例:
- Open Internet
1. 在 Test I 中,MappedAddr1 与本地地址相同;
2. 在 Test II 中可以收到响应。
3. 说明无 NAT 或路由器不进行地址转换。
- Full Cone NAT
1. Test I 中,MappedAddr1 ≠ 本地地址,表示存在 NAT;
2. Test II 中可以收到响应,说明对于外部地址/端口的变化并不受限;
3. 进一步测试可能仍会得到相同的 MAPPED-ADDRESS。
- Restricted Cone NAT 或 Port Restricted Cone NAT
1. Test I 中,MappedAddr1 ≠ 本地地址;
2. Test II 中收不到响应;
3. Test III 中,MappedAddr1 == MappedAddr2。
4. 说明对于来自外部的地址(或端口)存在一定限制,但对同一外部地址使用相同的映射端口。
- Symmetric NAT
1. Test I 中,MappedAddr1 ≠ 本地地址;
2. Test II 中收不到响应;
3. Test III 中,MappedAddr1 与 MappedAddr2 不同。
4. 说明在不同外部目的地址时,客户端会被 NAT 分配不同的映射端口。
小结
- RFC3489 的检测流程主要是依赖一台可以在"两个地址或端口"上提供 STUN 服务的服务器,通过客户端向这两个地址发送请求并观察响应结果来推断 NAT 类型。
- 关键属性包括 MAPPED-ADDRESS 和 CHANGED-ADDRESS,以及 CHANGE-REQUEST 选项,用来探测 NAT 对外部流量的限制程度。
- 典型的三个测试(Test I, Test II, Test III)可帮助判断是否有 NAT,以及 NAT 的类型是 Full Cone、Restricted Cone、Port Restricted Cone 还是 Symmetric。
- RFC3489 虽已被 RFC5389 取代,但它所示范的 NAT 探测流程仍然是理解 NAT 行为和 STUN 工作原理的经典参考。
评论
发表评论