前言
一直很想了解VMware的NAT模式使用的是哪一种类型的NAT,对于P2P应用的穿透难度如何。但是网上一直很少有测试。为此设计了一个实验,使用Stunserver+VMware来测试。先说结论VMware NAT 类型为 端口受限锥形(Port Restricted Cone),详细结论请看完文章。
前期准备
本次实验需要两台虚拟机,一台当做服务器,一台作为客户端:
在本地的VMware上部署一台Linux服务器,例如Rocky-Linux8.x,网络类型选择桥接模式,网络需要两张网卡,桥接到宿主机的网络。

另外部署一台Windows server2016,关闭Windows防火墙,使用NatTypeTester32在宿主机上当做客户端进行测试,选择NAT网络模式,确保能够访问到宿主机的网络。

具体配置如下:
| 组件 | 配置 |
|---|---|
| Linux 服务器(STUN 服务端) | Rocky Linux / OpenCloudOS,桥接网络模式,双 IP |
| Windows 客户端(NatTypeTester) | Windows 10/11,NAT 网络模式(VMnet8) |
| STUN 服务软件 | stunserver(源码编译) |
| 测试工具 | NatTypeTester(Windows) |
服务器部署
Linux 端:部署 stunserver
1、安装编译依赖
sudo dnf install -y gcc-c++ make boost-devel openssl-devel git
2、下载并编译 stunserver
sudo dnf install coturn -y
编译成功后,当前目录下会生成可执行文件 stunserver。雷点:若 make 报错,检查是否缺少 boost 或 openssl 开发包。OpenCloudOS 9 需确保 EPEL 源配置正确。
配置 Linux 双 IP(关键步骤)
ip addr show
添加辅助 IP(别名 IP)
若当前仅有一个 IP(如 192.168.101.127),需要为同一网卡添加第二个 IP:
sudo ip addr add 192.168.101.128/24 dev ens160
ip addr show ens160
# 应同时看到 inet 192.168.101.127/24 和 inet 192.168.101.128/24
雷点:
- 两个 IP 必须在同一子网(如
/24)。 - 辅助 IP 不能与其他设备冲突,先用
ping确认该 IP 未被占用。 - 该命令为临时生效,重启后失效。如需永久生效,需修改网卡配置文件(如
/etc/sysconfig/network-scripts/ifcfg-ens160)。
确认两个 IP 均能被客户端路由访问
ping 192.168.101.127
ping 192.168.101.128

启动 stunserver
参数名是 --altinterface 和 --altadvertised
nohup ./stunserver --mode full \
--primaryinterface 192.168.101.127 \
--altinterface 192.168.101.128 \
--primaryadvertised 192.168.101.127 \
--altadvertised 192.168.101.128 &
参数说明:
| 参数 | 含义 |
|---|---|
--mode full | 启用 Change-Request 支持(RFC 5780) |
--primaryinterface | 主 IP(监听 3478 端口) |
--altinterface | 辅助 IP(监听 3479 端口) |
--primaryadvertised | 通告给客户端的主 IP |
--altadvertised | 通告给客户端的辅助 IP |
验证服务状态
# 查看进程
ps aux | grep stunserver | grep -v grep
# 查看端口监听(应同时看到 3478 和 3479)
netstat -ulnp | grep -E "3478|3479"

防火墙放行
sudo firewall-cmd --permanent --add-port=3478/udp
sudo firewall-cmd --permanent --add-port=3479/udp
sudo firewall-cmd --reload

Windows 端:使用 NatTypeTester 测试
- STUN Server:填入 Linux 主 IP + 端口,如
192.168.101.127:3478(默认端口可以不填) - 勾选:
RFC 5780和RFC 3489

测试结果RFC 5780协议下:
| 结果项 | 含义 |
|---|---|
Binding test: Success | 基础通信正常 |
Mapping behavior: EndpointIndependent | 端点独立映射(锥形 NAT) |
Filtering behavior: AddressAndPortDependent | 地址和端口依赖过滤 |
| 结论 | 端口受限锥形 NAT(Port Restricted Cone) |
总结:VMware NAT 类型为 端口受限锥形(Port Restricted Cone)
详细行为解析(基于 RFC 3489 / 5780 分类测试):
| 测试维度 | 结果 | 含义 |
|---|---|---|
| 映射行为(Mapping behavior) | Endpoint Independent | 端点独立映射:从同一内部 IP 和端口发出的数据包,无论发往哪个外部目标,都会被 NAT 网关映射为同一个公网 IP 和端口。这属于锥形(Cone) NAT 的核心特征。 |
| 过滤行为(Filtering behavior) | AddressAndPortDependent | 地址和端口依赖过滤:外部主机只有在其 IP 地址和端口号 都与内部主机先前通信过的外部目标精确匹配时,才能向内网发送数据包。 |
综合判定(基于 RFC 5780 整合算法)为:PortRestrictedCone(端口受限型)
- 映射:采用锥形映射(同一个内网端口映射到同一个公网端口)。
- 过滤:采用端口受限过滤(即外部主机必须同时匹配 目标 IP + 目标端口 才能向内网发包)。
下面分析P2P难易程度
首先,P2P应用需要进行打洞,不同的NAT类型对其打洞难易程度不同。根据测试结果,这是一种“中等偏难”的 NAT 类型。P2P 打洞(UDP 穿透)可行,但条件苛刻、容错率低,远不如全锥形顺畅,但比对称型要好得多。下面是难易程度评价:
| NAT 类型 | 打洞成功率 | 难度等级 |
|---|---|---|
| Full Cone (全锥形) | 接近 100% | ⭐ (极简) |
| Address Restricted Cone (地址受限锥形) | ~90% | ⭐⭐ (简单) |
| Port Restricted Cone (端口受限锥形) | ~60% ~ 80% | ⭐⭐⭐⭐ (较难) |
| Symmetric (对称型) | < 10% (通常需要中继) | ⭐⭐⭐⭐⭐ (地狱级) |
为什么“端口受限锥形”打洞是可行的(优点):
- 端口稳定性:无论 Windows 虚拟机发往哪个外部目标(如 Peer A 或 Peer B),VMware NAT 网关都会将其映射为同一个公网端口(如
192.168.101.91:63552)。 - 这意味着:在进行 UDP 打洞时,双方不需要去猜测对方 NAT 分配的端口号,因为端口是固定的。这避免了对称型 NAT 中“端口预测”的噩梦。
为什么实际穿透非常艰难(缺点):
Filtering behavior: AddressAndPortDependent 是导致困难的根本原因。
- 严格的“白名单”机制:NAT 网关只会接受来自 “你之前恰好主动联系过的那台主机的那个特定端口” 的数据包。
- 现实场景困境:
- 假设 Peer A(外部公网 IP
1.2.3.4,端口12345)想给你发数据。 - 你的 NAT 网关之前只给 Peer B 发过数据,所以当 Peer A 发来数据时,即便 IP 是对的,只要 Peer A 的源端口
12345不是你之前联系过的那个端口,数据包就会被 直接丢弃(NAT 不会转发给 Windows 虚拟机)。 - 时间差问题:UDP 打洞要求双方几乎同时向对方的公网 IP 和端口发送数据包(并发打洞)。如果一方先发,另一方后发,先发的那一方由于还没收到对方的包,NAT 过滤表里没有对方记录,后发来的包就会被无情丢弃。
- 假设 Peer A(外部公网 IP
在真实的 P2P 网络(如 BitTorrent、WebRTC 音视频通话、游戏联机)中:
- 成功率(约 60%-70%):如果两台主机都是端口受限锥形,且双方都使用了标准的 并发打洞(Concurrent Connect) 算法,同时在几毫秒内向对方发送数据包,大概率能成功建立直连。
- 失败场景(约 30%-40%):
- 双方网络延迟差异过大(一方数据包先到达,另一方的 NAT 表还没生成,导致包被丢弃)。
- 其中一方使用的 P2P 库不支持并发打洞,只做单向穿刺。
- 端口复用冲突(主机内部多个程序占用了相同端口映射)。
技术架构上的妥协(ICE 策略)
在现代 P2P 架构(如 WebRTC)中,ICE(交互式连接建立)框架对你这类型 NAT 的处理策略是:
- 优先直连(srflx 候选):它会尝试让两端通过 STUN 获取的
192.168.101.91:63552进行双向 UDP 并发打洞。如果网络状况良好,这里会成功。 - 保底中继(Relay 候选):由于端口受限锥形的打洞存在不确定性,ICE 协议通常不会等待太长时间(通常只试几秒钟)。一旦打洞超时,流量就会立即切换到 TURN 服务器(中继转发)。
VMware NAT 的端口受限锥形,P2P 能通但全看“运气”和“算法”。 它需要两端严格的时间同步打洞,成功率约七成;失败时,就必须依赖 TURN 服务器中转,此时 P2P 的优势(低延迟、节省带宽)将荡然无存。这也是为什么主流 P2P 应用都会耗费巨资部署 TURN 服务器来兜底的原因。
建议
如果有P2P的需求建议优先选择桥接模式,比如qbit、彗星、PCDN等需求。
故障排查
stunserver 启动失败(退出码 255)
原因:参数错误、IP 不存在、端口被占用。
# 前台运行查看详细错误
./stunserver --mode full \
--primaryinterface 192.168.101.127 \
--altinterface 192.168.101.128 \
--primaryadvertised 192.168.101.127 \
--altadvertised 192.168.101.128
端口被占用
netstat -ulnp | grep -E "3478|3479"
# 如果被占用,杀掉占用进程
sudo pkill -f turnserver # 如果是 Coturn
sudo pkill -f stunserver # 如果是旧实例
辅助 IP 无法绑定
确认 IP 存在:
ip addr show | grep 192.168.101
若不存在,添加别名 IP:
sudo ip addr add 192.168.101.128/24 dev ens160
Windows 无法 ping 通 Linux
- 检查 VMware 网络模式:Windows 为 NAT,Linux 为桥接。
- 检查 Linux 防火墙:
sudo systemctl stop firewalld临时关闭测试。 - 检查 VMware 虚拟网络编辑器是否启用了 NAT 路由。

Comments NOTHING