我有一个主要在两个 Debian 系统之间工作的 wireguard 隧道,但我必须绕过 ISP 防火墙(下图中的防火墙 X),它会阻止所有入站内容并阻止服务器 B 直接监听 wireguard UDP 数据包。
为了绕过 ISP 防火墙,我在公共静态 IP 地址上使用了我的服务器(服务器 A)。服务器 B 受到 ISP 防火墙 X 的保护,该防火墙仅允许出站连接。服务器 B 也没有任何公共静态 IP 地址,因此它启动与服务器 A 的 SSH 连接,以建立从 A 到 B 的反向转发 TCP 隧道。然后,服务器 A 需要充当 wireguard 连接的模拟 UDP 端点,但 wireguard 未安装在那里。UDP 数据包需要使用服务器 B 预先建立的 SSH 反向转发隧道从服务器 A 传输到服务器 B。
实现方面,我继续socat
在服务器 A 上运行并监听 0.0.0.0:12345/udp。想法是让它将数据包转发到真正的 wireguard 服务器(在服务器 B 上),将收到的 UDP 数据包包装到 SSH TCP 反向转发隧道中。
也就是说,服务器 B 实际上是一台裸机服务器,它使用 libvirt 运行多个虚拟机。真正的 wireguard 服务器就是其中一个虚拟机。服务器 B 使用另一个socat
进程来解开 TCP 隧道 UDP 数据包并将其传送到运行 wireguard 的正确虚拟机。
据我所知,UDP 在互联网上本身是不可靠的,我甚至添加了几层封装,但是:
- 反向 ssh 隧道是 TCP 隧道,它应该是可靠的
- 这两个
socat
隧道都位于一台计算机内,因此我可以假设它们是可靠的 - wireguard 使用 UDP,它应该将所有可靠性检查捆绑在自身内
但是,从我的客户端来看,我的 wireguard 隧道的丢包率很高。在ping
其他不需要此ssh+socat
解决方法的 wireguard 隧道上进行同样的测试,丢包率为 0%。
我的问题是:如何调试此解决方案以找出 ping 数据包丢失的位置?
编辑:经过几次测试,我注意到当我尝试大量使用 vpn 隧道时,数据包丢失百分比会比ping
单独使用命令高得多,例如,如果我在客户端上打开指向其中一个虚拟机的浏览器。ping
单独使用命令实际上几乎 100% 可靠,例如,它偶尔会丢失一个数据包,但当浏览器加载页面时,它会开始丢失大量数据包(并且浏览器永远不会完成页面加载)。
我看到 socat 确实有一些缓冲区大小选项,但我不知道应该尝试哪些数字,所以我怀疑在黑暗中抛出数字不会让我快速解决问题……无论如何,在等待有人给出答案时,我会尝试大和小的随机数并报告:每次测试都需要一段时间。