一个 WireGuard 对等端不通而另一个正常:排查清单
能用的那一端只能证明它自己的密钥、端点和路由。在扩大任何规则之前,先比对失败对等端的 AllowedIPs、枢纽的转发以及内部的源地址。
一个 WireGuard 对等端能正常转发流量,另一个能完成握手却始终无法到达隧道另一端的任何东西。能用的那一端只能说明接口、UDP 端口和服务器密钥大概没问题。它对第二个对等端的 AllowedIPs、内部源地址以及中间的转发规则一无所知。按顺序执行清单,在第一个条件不成立的步骤停下。
步骤 1:写下数据包应当经过的路径
同一枢纽上的两个客户端不会自动互通。在枢纽与辐条结构里,服务器在 wg0 上收到数据包后必须再把它从 wg0 转发给另一个对等端,这需要开启 IP 转发并有一条转发规则。在直连的对等端结构中,双方都需要把对方的端点地址和对方的隧道地址放进 AllowedIPs。先确定你在排查哪种结构,再去看任何配置。
预期路径也告诉你去哪里看。如果数据包应当穿过枢纽,出错的一跳要么是发送方的 AllowedIPs,要么是枢纽的转发,要么是接收方的 AllowedIPs。如果应当直连,枢纽就无关紧要,重要的是两端对等端上的端点字段。
步骤 2:两端都要比对 AllowedIPs,不能只看一边
WireGuard 把 AllowedIPs 同时当作路由表和访问控制表。发送时,目的地址会在对等端的 AllowedIPs 里查找以选择隧道;接收时,内部源地址必须落在发送方对等端的 AllowedIPs 内,否则数据包会被丢弃。任意一侧缺少一段范围都会产生同样的症状:传输能通,内容消失。
读实时状态,不要只读配置文件,因为重新加载可能已经悄悄失败了:sudo wg show wg0 allowed-ips。在服务器上,失败对等端的条目必须包含它的隧道地址,例如 10.90.0.3/32。在客户端上,服务器对等端的条目必须包含你正在测试的目的地址,无论是枢纽的隧道地址还是远端子网。范围重叠会让查找产生歧义并可能选中你并不想要的对等端,所以务必让它们互不重叠。
步骤 3:检查内部源地址
一个客户端把 10.90.0.3 交给 wg0 路由,却从自己的 Wi-Fi 地址发出数据包,就会被对端拒绝,因为源地址与该对等端的 AllowedIPs 不符。用 ip route get 10.90.0.3 from 10.90.0.2 确认内核实际选择的是什么,再用 ip -brief addr show wg0 确认隧道接口上分配的地址。
在接收方 Linux 主机上,反向路径过滤是第二道关口。如果承载回程路由的接口上启用了严格的 rp_filter,回程路径与入站接口不一致的隧道流量就会被丢弃。先确认实际生效的值再决定关闭;在很多拓扑里,正确的做法是补一条路由,而不是放宽过滤。
步骤 4:检查枢纽的转发与回程路径
如果枢纽需要在各对等端之间转发,内核需要 net.ipv4.ip_forward=1,防火墙必须放行被转发的流:从 wg0 进、从 wg0 出,从发送方的隧道地址到接收方的地址。常见故障是 只放行了 UDP 51820 的入站规则,却没有转发规则],于是握手成功而数据死掉。用 sudo nft list ruleset 或你所用的防火墙管理工具相应命令列出生效的规则。
接着检查回程。目的主机必须有回到发送方的路由,经由枢纽或经由它自己的网关。如果枢纽还对隧道子网做了 NAT,要确认地址转换作用于被转发的流,并确认回程在状态过期之前回到枢纽。看起来像密钥问题的单向故障,往往只是这条回程路由。
最后,把握手和数据分开。能完成握手但大流量传输卡住的对等端,通常是那条路径上的 MTU 或 MSS 问题,而不是 AllowedIPs 问题。先用小包 ping,再用满尺寸 ping,然后比较两端。
步骤 5:只改一处,并保持能用的那一端不变
只在出问题的那条路径上做一处改动,然后重测两端。把所有对等端的 AllowedIPs 都换成 0.0.0.0/0,是弄坏本来能用的那一端最快的办法,因为它改变了该接口上所有流量的路由决策。只编辑那一条,重新加载,再把实时状态读回来。
记录哪条路径成功、哪条失败,以及每条命令的确切输出。这份对比比一句 VPN 坏了的笼统报告值钱得多,也是下一个人最先会要的东西。