skip to content
Liu Yang's Blog

NAT 穿透原理与 P2P 组网实践

/ 7 min read

Table of Contents

P2P 组网、局域网游戏联机、远程访问内网设备,这些场景都绕不开 NAT 穿透。本文从原理到工具整理一遍。

NAT 类型

路由器做 NAT 时,在内网 IP:Port 与公网 IP:Port 之间建立映射表。不同 NAT 对这个映射的开放程度不同,直接决定了打洞难度。

NAT1 — FullCone(完全锥形)

一旦内网设备向外发 UDP 包并建立映射,任何外部 IP:Port 都可以通过这个公网端口向内发包。打洞成功率 100%。

NAT2 — IP 限制锥

只有之前通信过的 IP(端口不限)才能通过映射向内发包。

检测方法:用另一个 IP 探测失败,但 STUN 服务器换个端口探测成功。

NAT3 — 端口限制锥

只有之前通信过的 IP + Port 完全匹配才能通过。

检测方法:另一个 IP 或 STUN 服务器的另一个端口探测都失败,但用 STUN 接收过的那个端口探测成功。

NAT4 — 对称 NAT(Symmetric)

同一内网地址向不同目标 IP 发包时,路由器会分配不同的公网端口。打洞极难。

内网 10.0.0.5:51820 -> STUN 服务器 => 公网端口 40123
内网 10.0.0.5:51820 -> 对方主机 B => 公网端口 40125(不同!)

控制服务器告诉对方的端口是 40123,但实际流量到达 B 时用的是 40125,打洞失败。

检测工具

Terminal window
# Windows(图形界面)
# https://github.com/HMBSbige/NatTypeTester
# Linux
pip install pystun3
python -m stun

打洞原理(以 Tailscale 为例)

NAT2 / NAT3 下可以打洞,核心流程:

  1. 双方各自向 STUN 服务器发 UDP 包,得到自己的公网 IP:Port

    • A → 203.0.113.5:40123
    • B → 198.51.100.9:51200
  2. 控制平面(Tailscale 协调服务器)把双方的公网地址互相通知

  3. 双方几乎同时向对方的公网地址发 UDP 包

    • A 发包到 198.51.100.9:51200
    • B 发包到 203.0.113.5:40123
  4. 第一个方向的包会被对方 NAT 丢弃(映射还没建立),但本方 NAT 已为这个目标建了映射

  5. 反方向的包到达时,命中了对方刚建的映射 → 穿透成功

“双方同时打洞”的关键就在这里:两边都先主动发包,让对方的回包能进来。

为何 NAT4 打洞失败

对称 NAT 会为不同目标分配不同端口。STUN 服务器得知的外部端口(40123)和实际发给对方时用的端口(40125)不一致,控制平面传递的信息就是错的,打洞必然失败。

有一些高级方案(端口预测、并发探测)可以在部分对称 NAT 下成功,但成功率不稳定,不作为常规方案。


打洞失败时的中继方案

方案 说明
Tailscale DERP 官方中继,全球分布,自动回退
Headscale + 自建 DERP 完全自托管,适合隐私要求高的场景
Tailscale Peer Relay 新功能,支持更灵活的中继路由策略
frp 有公网服务器时的轻量级穿透方案
gost 万能隧道工具,也可以做端口中继

有公网服务器的情况下(例如国内轻量云、阿里云 ECS),frp 或 gost 都是简单可靠的选择,延迟也更可控。


P2P 组网工具对比

工具 打洞能力 中继 特点
Tailscale 强(NAT2/3) DERP / 自建 最易用,有官方控制平面
Headscale 同上 需自建 DERP 开源,完全自托管
ZeroTier 中等 ZeroTier Planet 去中心化设计,有官方 Planet
EasyTier 中等 可自建 国产轻量,配置简单
N2N 基础 supernode 老牌方案,资源占用极低
WireGuard 需手动配置 无内置 性能最强,无自动打洞,适合固定公网 IP 场景

局域网游戏联机

局域网游戏通过向 255.255.255.255 广播 UDP 包传播房间信息。问题在于:Windows 只在首选网络接口上发广播,虚拟局域网的接口收不到,所以虚拟组网后搜不到房间。

解决方案:

  • WinIPBroadcast:监听所有全局 UDP 广播包,重发到每个网卡接口
  • EasyN2N:集成了 N2N + WinIPBroadcast,打包好开箱即用

适用场景:Hamachi 替代品、老游戏局域网联机、棋牌类游戏。


UDP 流量接管工具

部分应用(含游戏)不走系统代理,需要虚拟网卡在系统层面接管 UDP 流量:

工具 平台 说明
tun2socks 跨平台 将 TUN 接口流量转发到 SOCKS
Wintun Windows 高性能 TUN 驱动,WireGuard 所用
WinPcap / Npcap Windows 数据包捕获,底层级别
gost 跨平台 多协议隧道,也可接管流量

有中心服务器的游戏(Apex、CS2):只要 UDP 能进代理,基本正常游戏,无需代理 ICMP。

P2P 游戏:需关注 NAT 类型,现代协议大多能做到 NAT1,通常不是瓶颈。


参考