NAT类型和STUN协议
端点(endpoint) = IP + 端口(port)
NAT(Network Address Translation)本质上是在内网端点和 NAT 设备的公网侧端点之间建立映射。内网主机访问公网时,NAT 设备会把内网主机的 IP:端口 映射成它的公网侧的 IP:端口(也称 SNAT)。NAT 设备会在一段时间内记住这个映射,以便公网返回的数据包能被转发回内网主机的端点(也称 DNAT)。
不过,不同 NAT 设备建立映射和过滤返程流量的行为并不完全相同。对普通网页访问来说,这些差异通常不太明显;但对 P2P、VoIP、WebRTC、游戏联机等场景来说,这些差异会产生不小的影响。为了标准化,我们可以把不同 NAT 设备的行为归类成不同的 NAT 类型。
NAT 类型
传统 NAT 分类方式通常把 NAT 分为四种:
- Full Cone NAT
- Restricted Cone NAT
- Port Restricted Cone NAT
- Symmetric NAT
现代 NAT 分类方式则倾向于把 NAT 行为拆成两个维度:
- 映射行为(Mapping Behavior):内网端点会被映射成 NAT 设备的哪个公网侧端点。
- 过滤行为(Filtering Behavior):公网的哪些数据包可以被放行回到内网主机的端点。
传统分类方式比较直观,但它把“映射”和“过滤”两个行为混在了一起。现代分类方式则更精确、有更高的细粒度。由于传统的四种类型可以看作现代的两个维度的特定组合,这里将主要介绍现代 NAT 分类方式。
映射行为(Mapping Behavior)
映射行为描述的是:同一个内网端点访问不同公网端点时,NAT 设备是否复用同一个公网侧端点。
Endpoint-Independent Mapping
端点无关映射(Endpoint-Independent Mapping,EIM)表示:只要内网端点相同,无论访问哪个公网端点,NAT 设备都复用同一个公网侧端点。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。192.168.1.2:50000 -> 1.1.1.1:20000仍然映射为<WAN-IP>:40000 -> 1.1.1.1:20000。192.168.1.2:50000 -> 2.2.2.2:20000仍然映射为<WAN-IP>:40000 -> 2.2.2.2:20000。
Address-Dependent Mapping
地址相关映射(Address-Dependent Mapping,ADM)表示:NAT 设备是否复用公网侧端点,取决于所访问的公网端点的 IP,但不关心它的端口。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。192.168.1.2:50000 -> 1.1.1.1:20000仍然映射为<WAN-IP>:40000 -> 1.1.1.1:20000。192.168.1.2:50000 -> 2.2.2.2:10000映射为<WAN-IP>:40001 -> 2.2.2.2:10000。
Address and Port-Dependent Mapping
地址和端口相关映射(Address and Port-Dependent Mapping,APDM)表示:NAT 设备是否复用公网侧端点,同时取决于所访问的公网端点的 IP 和端口。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。192.168.1.2:50000 -> 1.1.1.1:20000映射为<WAN-IP>:40001 -> 1.1.1.1:20000。192.168.1.2:50000 -> 2.2.2.2:10000映射为<WAN-IP>:40002 -> 2.2.2.2:10000。
过滤行为(Filtering Behavior)
过滤行为描述的是:NAT 映射建立后,哪些来自公网的数据包可以通过 NAT 设备公网侧端点、转发到内网主机。
Endpoint-Independent Filtering
端点无关过滤(Endpoint-Independent Filtering,EIF)表示:任意公网端点都可以通过 NAT 设备的公网侧端点发送数据包。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。1.1.1.1:10000发来的包会被放行。1.1.1.1:20000发来的包会被放行。2.2.2.2:10000发来的包会被放行。
Address-Dependent Filtering
地址相关过滤(Address-Dependent Filtering,ADF)表示:只有和之前主动联系的公网端点相同 IP 的端点才能通过 NAT 设备的公网侧端点发送数据包。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。1.1.1.1:10000发来的包会被放行。1.1.1.1:20000发来的包会被放行。2.2.2.2:10000发来的包不会被放行。
Address and Port-Dependent Filtering
地址和端口相关过滤(Address and Port-Dependent Filtering,APDF)表示:只有之前主动联系的公网端点才能通过 NAT 设备的公网侧端点发送数据包。
例如:
192.168.1.2:50000 -> 1.1.1.1:10000映射为<WAN-IP>:40000 -> 1.1.1.1:10000。1.1.1.1:10000发来的包会被放行。1.1.1.1:20000发来的包不会被放行。2.2.2.2:10000发来的包不会被放行。
传统 NAT 类型与现代 NAT 类型的关系
| 传统 NAT 类型 | 映射行为(Mapping Behavior) | 过滤行为(Filtering Behavior) |
|---|---|---|
| Full Cone NAT | Endpoint-Independent Mapping | Endpoint-Independent Filtering |
| Restricted Cone NAT | Endpoint-Independent Mapping | Address-Dependent Filtering |
| Port Restricted Cone NAT | Endpoint-Independent Mapping | Address and Port-Dependent Filtering |
| Symmetric NAT | Address and Port-Dependent Mapping | Address and Port-Dependent Filtering |
STUN 协议
STUN 协议可以帮助探测 NAT 类型。它的工作原理可以简单描述为:
- 客户端向 STUN 服务器发送
Binding Request。 - STUN 服务器观察这个请求的来源端点。
- STUN 服务器在响应中通过
XOR-MAPPED-ADDRESS告诉客户端:服务器看到你的来源是哪个端点。 - 客户端拿着这个公网端点,和自己刚刚用来发送请求的本地端点对比,就能知道自己是否经过了 NAT,以及 NAT 的具体映射。
有些支持 RFC 5780 的 STUN 服务器拥有多个端点,涵盖了不同 IP 和不同端口,比如 <PRIMARY-IP>:10000,<PRIMARY-IP>:20000,<ALTERNATIVE-IP>:10000。客户端用同一个本地端点分别访问这些端点,观察映射是否变化,就能知道 NAT 设备的映射行为;同时客户端也可以要求服务器从不同端点发送响应,通过观察 NAT 设备是否放行,从而判断出过滤行为。
举个例子:
1 | |