mihomo 的 Tun 模式和 RustDesk 冲突

rt, 同一个服务器上部署 mihomo 和 rustdesk 的话, 如果 mihomo 开启 tun 模式, 那么就会导致 rustdesk 的自部署模式出现异常。
暂时找不到问题的原因。
服务器暂时不部署 mihomo 的 tun 模式,如果功能需要开启的话, 到时候再手动开启关闭。

Clash TUN 模式下的 UDP 服务异常诊断与解决 - 4xpl0r3r’s blog

问题背景 Background

在我的日常生活中,我已经习惯通过ClashX的TUN模式(增强模式)接管MacOS系统的所有流量,便于观察实时流量并配置规则。Clash作为Surge的平替,已经成为了我在MacOS系统中的出口流量管理中心和出口防火墙。

MacOS的入口流量管理还是推荐使用PF防火墙

最近随着幻兽帕鲁的爆火,我在本地建立专用服务器后,发现局域网可以正常登录,来自公网的客户端却显示无法连接(我拥有公网IP并已建立好公网映射)。

问题诊断 Troubleshooting

UDP&TCP 进出流量检查

TCP出口流量,很容易测试,可以发现流量分流运行正常

image-20240229144359702|500

image-20240229144451892|500

TCP入口流量,可以发现也可以正常通过公网IP访问,也可以正常双向通信(Hello从客户端发到服务端,Back从服务端发回客户端)

image-20240229144918734|500

image-20240229144946166|500

UDP出口流量,这里我们尝试访问谷歌的NTP服务,可以发现正常建立连接

image-20240229145054536|500

UDP入口流量,我们先建立测试服务

image-20240229145229874|500

尝试发送一个UDP包,可以发现成功接收到数据包?似乎UDP监听目前也可以正常使用?事情真的如此吗?

image-20240229145313016|500

尝试发送响应包,我们发现客户端无法接收到。让客户端再次发送请求包,我们发现服务端也无法接收到。

image-20240229145830292|500

image-20240229145708448|500

此时在局域网中或不开启TUN进行测试,所有连接均正常,方法也一样,就跳过了

Wireshark分析

此时我们已经确认了问题,让我们用Wireshark深入诊断一下,在使用Wireshark监听的同时再次复现上文中出现问题的操作

你可能发现了此时我的公网IP和端口改变了,IP从218.79.x.x变为117.131.x.x,端口变为50011,不要在意这个

我们可以发现第一个成功发送的UDP数据包,目标端口是50011,这个数据包我们在服务端正常收到了

image-20240229150452204|475

第二个数据包是服务端返回发送的数据包,在客户端中我们并没能收到。图中可以看到Source Port为50131,这与服务开放的端口50011并不一致,此处我猜测是Clash在TUN NIC中对Source Port进行了重新映射,避免多个代理客户端发送了同样的Source Port产生冲突。那么因为Source Port和客户端发出的Destination Port不同,由于目前广泛采用的端口受限型NAT(在PlayStation中被称为NAT3),所以无法成功连接。此时如果客户端是地址受限型NAT(NAT2)或完全圆锥形NAT(NAT1),我推测是可以正常通信的。

问题解决 Solve it

此时我们已经确定了问题的原因——UDP服务出口流量经过TUN网卡导致Source Port不正确,无法与客户端构建连接。那么我们应该如何解决呢?

方案1 - 手动管理路由表

既然问题出在流量经过TUN网卡,那么我们可以为特定客户端IP指定路由表规则,让其直接使用物理网卡,忽略TUN网卡。

在MacOS中,我通过如下命令指定去往117.131.x.x的流量直接使用en20物理网卡,成功解决问题。

1sudo route add 117.131.x.x -interface en20

更换ClashX客户端为ClashX.Meta,其允许对TUN功能进行更详细的配置,我们也可以编写配置文件以使其自动排除特定的网段

1
2
3
tun:
inet4-route-exclude-address:
- 117.131.x.x/32
缺陷
  • 此方法只能用于经常通信的几个客户端

方案2 - 使用端口转发工具

一些端口转发工具可以指定使用的监听地址,并且从对应的网卡发送响应数据包。如 gost

使用gost绑定物理网卡对应的地址,进行流量转发

1gost -L=udp://192.168.x.x:50111/127.0.0.1:50112

客户端可以正常发送数据包,也可以正常收到响应数据包

image-20240229154654997|500

缺陷
  • 流量增加一层应用层转发,增大了服务器性能压力,也增加了网络延迟
  • 服务端应用无法正确判断客户端真实地址

方案3 - 网卡桥接

仅为猜想,并未测试

可以使用Vmware添加桥接网卡,直接接入物理网卡,即可忽略Clash TUN网卡

缺陷
  • 路由器的端口转发很可能不认桥接网卡,导致无法连接(我就遇到了这个情况,华为k662c路由器的端口转发无法绑定桥接设备的端口)

mac 上的 quanx 和 RustDesk 模式的冲突

需要开启兼容模式 (enhanced compatibility),才能解决问题。
原因未知。
通常情况下, 打开即可。

mac 连接手机热点, 连接不上 RustDesk

疯狂报错

[2024-12-31 18:38:13.996666 +00:00] INFO [src/rendezvous_server.rs:597] IP change of 405013531 from [2408:823d:1c10:17c0:a0eb:7c15:8b83:d5fb]:63387 to [2408:843c:1c00:ac25:68ea:2aa9:a2c:6da9]:62491
[2024-12-31 18:38:18.074402 +00:00] INFO [src/rendezvous_server.rs:597] IP change of 405013531 from [2408:823d:1c10:17c0:a0eb:7c15:8b83:d5fb]:63387 to [2408:843c:1c00:ac25:68ea:2aa9:a2c:6da9]:62491
[2024-12-31 18:38:21.026853 +00:00] INFO [src/rendezvous_server.rs:597] IP change of 405013531 from [2408:823d:1c10:17c0:a0eb:7c15:8b83:d5fb]:63387 to [2408:843c:1c00:ac25:68ea:2aa9:a2c:6da9]:62491
[2024-12-31 18:38:24.040036 +00:00] INFO [src/rendezvous_server.rs:597] IP change of 405013531 from [2408:823d:1c10:17c0:a0eb:7c15:8b83:d5fb]:63387 to [::ffff:122.193.199.31]:11520
[2024-12-31 18:38:24.130145 +00:00] INFO [src/peer.rs:102] update_pk 405013531 [::ffff:122.193.199.31]:11520 b"8C7143F9-F512-5021-A842-536C184A3822" b"S:\xc9\x95u\x05\x93\xf1v\xf7\x9bN\xc7:\x07\xa4\xf9\x963'4\xb4\xc9\xdcA-\xf4\xf7\xc7\xf0\x12\xc4"
[2024-12-31 18:38:24.136794 +00:00] INFO [src/peer.rs:130] pk updated instead of insert

尝试修改网络配置, 固定 ipv6 地址。

|500

问题修复。

好像需要同时配合重启 rustdesk。 怀疑是热点的逻辑问题,导致无法正确的识别 ipv6 的地址。

linux 配置代理

因为服务器上装了 mihomo, 而且又不能开启全局模式, 所以考虑使用代理的逻辑。