在折腾局域网和内网穿透时,我们经常会混用各种物理机和虚拟机。但有时候,一些看似顺理成章的网络访问,却会引发灾难性的“网络死锁”。
今天来复盘一个非常经典的嵌套网络冲突问题:通过虚拟机做内网穿透时,反向 RDP 宿主机导致整个网络崩溃。
🌐 诡异的场景还原
假设你的局域网内有这样一套拓扑:
- 机器 B:物理机(宿主机,运行 Windows)。
- 机器 C:运行在机器 B 上的 VMware 虚拟机(Ubuntu),配置了公网 IP 或内网穿透,作为外部访问局域网的“网关”。
- 机器 A:局域网内的另一台被控物理机。
日常链路很通畅:你在外网用笔记本,通过机器 C 穿透进局域网,顺利 RDP 远程控制了机器 A。
灾难触发点:当你试图在机器 A 上,再次使用 RDP 去控制机器 B 时,整个网络瞬间崩溃!你的笔记本不仅断开了与机器 A 的连接,作为网关的机器 C 也彻底失联,必须重启才能恢复。
除此之外,平时你甚至无法通过机器 C 映射出去的端口去访问机器 B。这到底是怎么回事?
🔍 核心原理解析
这其实是由两个深层的网络与虚拟化机制共同导致的:
1. 端口映射失效的元凶:非对称路由 (Asymmetric Routing)
为什么机器 C 无法把端口映射给机器 B?问题出在“回包”上。
当你通过外网访问机器 C,C 把流量转发给 B 时,机器 B 收到的数据包源 IP 依然是你的外网 IP。
机器 B 处理完请求后,发现目标是个外网地址,它会直接把响应数据扔给局域网的默认物理路由器,而不是原路还给机器 C。这就导致 TCP 握手失败,形成了“回环路由黑洞”。
2. RDP 导致断网的元凶:驱动死锁与会话挂起
当外网流量通过机器 C 流向机器 A 时,所有数据都在通过机器 B 的物理网卡和 VMware Bridge Protocol(虚拟网桥驱动)。
当你从机器 A 突然发起高强度的 RDP 连接访问机器 B 时:
- VMware 网桥崩溃:大量真实的局域网流量(A 到 B)与虚拟机的回环转发流量(C 到 A)在宿主机网卡底层交汇,极易触发虚拟网桥的混杂模式死锁,导致机器 C 的虚拟网卡直接断流。
- Windows 会话切换(最致命):VMware Workstation 是桌面级软件,依赖当前用户的图形会话。当你通过 RDP 连接 Windows 宿主机时,系统会强制锁定本地屏幕并分配新的远程会话。在这个切换瞬间,运行在前台的 VMware 进程会被系统挂起,底层的虚拟网络服务瞬间离线,你的穿透隧道也就被强行掐断了。
🛠️ 终极解决方案
理清了病因,解决起来就有的放矢了。以下是几个层次的解决方案:
方案一:修复端口映射(开启 SNAT)
在 Ubuntu (机器 C) 上配置端口转发时,不仅要做目标地址转换(DNAT),必须同时做源地址伪装(SNAT)。
如果你使用 iptables,请务必加上这条命令,让机器 B 以为是机器 C 在和它通信:
sudo iptables -t nat -A POSTROUTING -d [机器B的IP] -p tcp --dport [机器B的端口] -j MASQUERADE
方案二:规避 RDP 会话切换(临时避险)
不要使用 RDP 去连接作为 VMware 宿主机的机器 B。在机器 A 上,改用 AnyDesk、RustDesk 或 ToDesk 等无需接管 Windows 底层会话的远控软件。这样不会触发 Windows 的屏幕锁定,VMware 进程也就不会被挂起。
方案三:更改虚拟机网络模式(降低桥接风险)
将 VMware 中机器 C 的网络模式由“桥接模式(Bridged)”改为 “NAT 模式”。在 NAT 模式下,宿主机会代为处理路由,能有效避免物理网卡驱动在处理复杂回环流量时发生死锁。
方案四:架构降维打击(根本解决)
VMware Workstation 本质上是桌面软件,并不适合用来运行核心的“网络穿透网关”。
- 迁移至 Hyper-V:如果你必须在 Windows 上跑这个网关,请开启 Windows 自带的 Hyper-V。它是 Type-1 级底层虚拟化,作为系统服务运行,完全不受 RDP 会话切换的影响。
- 物理隔离:花一两百块钱买个树莓派或二手瘦客户机,把内网穿透服务独立出来。网络基础服务,越底层、越物理越稳定!
总结:在复杂的局域网穿透中,尽量避免让宿主机和它身上的虚拟机产生复杂的“网络套娃”通信。搞懂底层路由和驱动机制,才能优雅地避开这些隐形大坑!
版权属于:soarli
本文链接:https://blog.soarli.top/archives/826.html
转载时须注明出处及本声明。