WireGuard 默认路由回环:找到端点路径
默认路由会把隧道自身的加密数据包送回隧道内部。请先读取端点路径,添加一条主机路由,然后验证并回滚。
接口已经起来,对端配置看起来也没问题,但握手始终无法完成。通过隧道添加默认路由往往正是起因:同一张路由表现在要决定隧道自身加密数据包的走向,而它给出的答案又回到了隧道里。没有任何东西能承载那个本应承载内层数据包的外层数据包,于是连接在开始之前就卡住了。修复很小,但有先后顺序,而且验证比改动更重要。
改动路由之前先确认回环
读取对端当前的端点地址,然后问路由栈:发往该地址的数据包会走哪条路。如果答案指向隧道接口,回环就已确认,无需进一步诊断。动手之前先把这两条输出存入变更记录,因为修复后的对比用的正是同样两条命令。回环一旦看见就不难理解;难的是它发生时接口看起来仍然健康。
sudo wg show wg1 endpoints
ip route get 198.51.100.20
ip rule show
把策略规则也纳入这次记录。一条在主表中看似正确的默认路由,仍可能输给为带标记或不带标记流量选择另一张表的规则,回环就会在一张看起来没问题的路由表上重新出现。
读端点路径,而不是隧道路径
端点路径是加密数据报发往对端公网地址所走的路径,只要隧道存在,它就必须留在隧道之外。隧道路径则是允许对端承载的一切。这两条路径共用同一张路由表,正因如此,一条包罗万象的条目就能让它们彼此塌缩。把隧道流量与隧道自身的传输分开,正是整个设计问题,而每种受支持的工具解决它的位置都略有不同。
如果接口同时承载两种地址族,就分别检查。IPv4 的排除有效,并不说明 IPv6 端点是否仍然可达;混合配置可能一直看起来正常,直到选中对端的 IPv6 地址。
用一次连贯的改动恢复端点路径
有两种受支持的做法,把它们混用正是让可用配置变得不可预测的原因。第一种是让拥有该接口的工具管理整条隧道:wg-quick 对默认对端范围有专门处理,会安装 一张独立的表、策略规则和一个套接字标记,从而把外层数据包挡在隧道之外。让这套机制保持完整,不要手工复制其中一半。把手工添加的默认路由与已经安装标记和规则的管理器混在一起,往往在重连后失败,因为管理器会重写手工步骤所假定的状态。
第二种是手工设计:让端点通过物理网关获得一条明确的主机路由。先于默认路由添加它,用替换而不是追加,以免旧条目继续生效,然后再确认查找结果。
sudo ip route replace 198.51.100.20/32 via 192.0.2.1 dev eth0
ip route get 198.51.100.20
sudo ip route add default dev wg1
验证,然后保留回退手段
不断推进的握手时间戳是第一项证据,它比一个仅仅存在的接口更有力。接着通过隧道做一次应用测试,然后故意把接口关掉,确认主机回到可用状态,而不是留着一条指向虚空的默认路由。最后这一步常被跳过,而它恰恰决定重启后机器会不会失联。
sudo wg show wg1 latest-handshakes
sudo wg-quick down wg1
ip route show default
ip route get 198.51.100.20
在做这些之前,先保存当前路由状态,并确保有一条不依赖隧道的进入途径:控制台、带外管理地址,或一位在机房的同事。丢失默认路由的远程机器,无法再通过它刚刚失去的那条连接恢复,而最安全的操作手册步骤,永远是在第一条命令之前完成的那个。