两个对等端列出了彼此相接的网段,流量却送到了错误的一方。没有任何损坏:WireGuard 通过将目的地址与已配置的网段进行匹配来选择对等端,最具体的匹配胜出。在扩大任何范围之前,先确定哪个对等端应当拥有哪个前缀。

在 WireGuard 内部,最长前缀胜出

每个对等端条目都带有一组目的前缀。数据包被路由到接口时,实现会寻找匹配前缀最具体的那一条,这与路由表所适用的规则相同。因此 /24 会胜过包含它的 /16,较窄的对等端会收到流量。

Road-warrior 部署会有意利用这一点。一个对等端拥有某个站点的宽网段,单个主机则用属于其他对等端的 /32 条目切分出来。这种模式之所以有效,是因为切分更具体,而不是因为顺序。

把归属关系写成前缀与对等端的表格。如果两条条目描述同一个前缀,配置表达的就不再是意图,而是一场竞速。

操作系统先选择接口

WireGuard 只在一个接口上的对等端之间选择。 哪个接口收到数据包更早就已确定,由主机的路由表决定,而第二条默认路由或一条陈旧路由可能把流量送到对等端列表永远看不到的地方。这就是为什么对等端层面的诊断可能正确,却仍然解释不了故障。在读对等端配置之前先检查通往目的地的路由,因为指向物理接口的路由会让整个问题失效。

工具通常根据对等端网段安装这些路由,这意味着改动一个对等端的列表可能会悄悄把原本属于另一个对等端的流量改道。因此编辑对等端其实是伪装成配置的改路由。要同时审查两者,否则你会修好一个、弄坏另一个。

入站数据包按来源检查

网段列表承担双重职责。 对出站流量,它按目的地址选择对等端;对入站流量,它授权一个来源地址。来自该对等端网段之外地址的数据包,在任何防火墙看到它之前就会被丢弃。

只读配置的一侧时,这种不对称很容易被忽略。一个能到达某个子网的对等端,并不因此就有权从该子网发送;两个方向由不同的检查来强制执行。

窄的来源归属把这变成优势。给每个对等端一个用于自身地址的 /32,下游防火墙就有了可信的来源可以匹配,而不是一个全组共享、任何成员都能主张的网段。

重复的网段不是故障转移

把同一个前缀分配给两个对等端,并不会创建负载均衡器或备用路径。没有健康检查,也没有会话亲和:胜出的条目由实现的内部顺序决定,而那并不是可以用来设计的契约。如果需要备用出口,请在定义选择的地方表达。路由策略、度量值,或一对各自有记录归属者且互不相同的前缀,才能产生可预测、可测试的行为。

为了修复一个不相关的故障而扩大网段,是另一种常见错误。它会把流量从原本正常工作的对等端上移走,而新症状会在旧问题被理解之前出现。

编辑前先验证选择

三条命令依次回答三个问题。第一条列出每个对等端主张的网段。第二条显示主机去往某个目的地会使用哪个接口。第三条显示流量经过之后对等端的实时状态。

wg show wg0 allowed-ips
ip route get 10.66.8.20
wg show wg0
ip rule show

在变更前后各运行一次并对比。如果路由输出变了,但流量仍然到达错误的对等端,说明前缀列表以你尚未记录的方式重叠。如果路由输出没有变,说明对等端配置从来就不是被查询的对象。

把目的地、所选接口和所选对等端记录在工单里。正是这三元组让重叠在以后可以复查,它比一张配置截图有用得多。

相关文章