最新的握手字段为空,通常意味着接口启动后还没有完成过握手,这不代表配置一定有问题。WireGuard 会一直保持沉默,直到有数据包需要从接口发出,因此空闲的对端没有东西可发时,报告的就是这种状态。在检查密钥之前,先确认是否真的发送过什么。

测试方法就是朝对端应当承载的目标发送一个被允许的数据包。状态屏幕上的其他内容描述的都是意图,而不是实际活动。

空闲接口没有什么可报告的

WireGuard 的握手是惰性的:第一个需要该隧道的包才会触发交换,在那之前接口一直安静。一个配置好却从未使用过的对端,会显示空握手、零接收字节,以及距上次握手不断拉大的间隔。这种状态对空闲客户端是健康的,只有在你原本期待流量已经通过时才需要警惕。也要看传输计数器,因为它们能区分「什么都没发」和「试过但失败」。

如果两端计数器都为零,问题就在隧道之上。没有任何数据到达接口去触发任何东西。

触发对端被允许承载的流量

在本机选择对端允许前缀内的地址,并确认路由表会把它从接口发出去。前缀之外的目标只会产生普通的经路由请求,与 WireGuard 完全无关。用一个响应很快的服务,例如 ping 或短 TCP 连接,让这次尝试有明确的开始和结束。然后重新读取握手那一行,而不是盯着屏幕等待。

ip route get 10.60.9.5
ping -c 3 -W 2 10.60.9.5
wg show wg0 latest-handshakes
wg show wg0 transfer

路由查询比 ping 更重要。如果它指向物理接口,数据包根本没有进入隧道,空握手是路由层面的答案,而不是密码学层面的。先修好路由,再调试对端。

比较密钥对与端点

流量确实被提供之后,下一步检查的是身份。本地私钥必须与远端授权的公钥对应,配置的远端公钥必须指向预期的对端,任何预共享密钥都必须在两端一致。base64 密钥里只差一个字符,就会得到一个看起来已配置、却永远完不成交换的对端。应当与配置记录比对,而不是重新生成密钥,因为新密钥会让所有信任旧密钥的对端失效。

端点也需要同样的检查:主机名、地址、UDP 端口,以及用于访问的地址族。过期的地址或错误的端口带来的是沉默,而不是提示。

观察外部 UDP 路径

握手以 UDP 形式发往端点,所以外部路径必须能承载它。下面的命令分别检查是否存在监听、本地协议栈是否真的发出了数据报,以及配置的是哪个端点。抓包要在触发流量的同时进行,而不是提前。

ss -lunp | grep 51820
sudo tcpdump -ni eth0 udp port 51820
wg show wg0 endpoints
conntrack -L -p udp | grep 51820

抓包只看到发起、没有回应,说明问题在机器之外,因为远端要么没在监听,要么被过滤,要么地址不对。抓包什么都没有,说明包根本没出去,这就把问题带回路由,以及任何在用到的 socket 标记。两端都由你管理时,用服务器上范围更窄的抓包按时间戳对照这次尝试,而不是用泛泛的抓包。TCP 端口测试在这里证明不了什么,因为该协议只有 UDP。

握手出现之后,通过隧道测试应用,因为完成的交换证明的是身份与可达性,而不是可用的吞吐或正确的 DNS。把变更前后的状态输出都保留下来,差异就是你的证据。

相关文章