@
cnbatch @
RobinHuuu 经过排查,不是 MTU 的问题,但是感谢提供 ping 的思路,通过 ping 发现具体的问题了。
通过 ping ,发现只有 icmp_seq 序号为偶数( 0 、2 、4……)的 ping 包才能收到响应,而奇数的包都是超时。就去排查 nftables 规则,发现问题所在:
我给指定服务器做转发,是在 nat 的 prerouting 链上判断目标地址为 17 服务器的包打上 meta mark ,然后在 ip rule 里匹配 fwmark lookup 表,default 路由到 Wireguard 的 wg0 出口。
看了下文档,nat 链只在第一个包会命中,后续包就跳过了。因为有 conntrack 跟踪数据包信息,所以 UDP 包也是只在第一个包会命中,后续包不会命中,导致只有第一个握手包发给了 Wireguard ,后续包都从物理网卡直接出去了,导致了 conntrack 同一个内网 IP + 端口对应不同的出口,触发了 conntrack 的 destroy ,所以服务端响应的包就找不到 NAT 回复的目标了。
我自己写的 UDP 测试程序之所以没问题,是因为每次电脑端每次发送都是用的随机 UDP 端口发一个包,conntrack 只跟踪第一个包,所以正常。如果给客户端代码也加上 bind ,使用相同端口来请求,就会发现和 ping 一样的,一次通,一次不通,分别是 conntrack 的 NEW 和 DESTROY 。
解法是在 meta mark set 的同时加上 ct mark set meta mark 给 conntrack 也打上标记,然后加了个 filter prerouting 的 mangle 链,匹配 ct mark 也设置上 meta mark set 就好了。