ip -4 rule add table main suppress_prefixlength 0
该命令出现在连接wireguard vpn的过程中。
2 回答
用wireguard 的三个潜在路由考虑因素来解释这一点可能是最容易的。
当您创建一个wireguard 接口时,您显然希望通过wireguard 访问您想要访问的IP 范围的数据包通过该接口。因此,如果您通过 wg0 上的 wireguard 访问 10.2.0.0/16,您可以执行ip route add 10.2.0.0/16 dev wg0
.
如果您只是连接到专用网络,则此方法有效。但是,如果您希望所有内容都通过wireguard 路由,因为它是您的默认路由呢?这带来了复杂性,因为当您希望通过wireguard 接口路由所有内容时,您显然不希望wireguard 自己的数据包通过该接口路由;否则,他们根本不会去任何地方。试一试ip route add 0.0.0.0/0 dev wg0
,现在什么都不起作用:传输 wg0 的数据包会尝试通过 wg0。您可以为每个wireguard peer 添加特定的路由,但是您可能有很多wireguard peer,这样会很不方便。
相反,wg-quick 使用防火墙标记 (fwmark),以便路由可以识别该接口的数据包,并以不同方式处理它们。通过设置类似wg setconf wg0 fwmark 51820
,wireguard 可以添加规则以区别对待wireguard 数据包和非wireguard 数据包。然后,它会创建一个不同的路由表(例如,51820,您可以通过 看到ip route list table 51820
),非wireguard 数据包会通过哪些路由表,并通过wg0 将它们全部路由,而wireguard 数据包会通过主表(您使用 看到的内容ip route list
)。它使用一条规则(并非来自所有 fwmark 0xca6c 查找 51820)将任何不是wireguard 数据包的内容转移到 51820 表(您可以使用ip rule
或来查看这些规则ip -6 rule
)。
那么现在,为什么from all lookup main suppress_prefixlength 0
?在许多情况下,您实际上并不需要它:wireguard 数据包将在主表上路由,而非wireguard 数据包将在 wg-quick 创建的表上路由。但是,如果您的主路由表不仅仅是默认路由怎么办?如果你添加了其他更具体的路由,可能是为了一些私有地址空间 VPN(我必须弄清楚这个命令做了什么的原因),或者可能是为了首先到达一些对等点: 也许他们在不同的界面上?
为了涵盖这些情况,第三个命令添加了一条规则,首先,查找任何数据包(来自所有)在主表上的路由(查找主表)。然后,它查看该路由的具体程度,例如,它的前缀长度是多少。如果它是 0 或更少(即默认路由,0.0.0.0/0 或 ::/0),它会抑制该路由(suppress_prefixlength 0),并继续查看下一个规则。如果它大于 0(例如,10.1.0.0/16),则它使用该路由。
因此,您最终会得到如下ip rule list
所示的规则(令人讨厌的是,ip 规则将固件标记显示为十六进制,因此 0xca6c,而wireguard 将其设置为十进制,因此 51820):
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main
一个可能看起来像这样 ( ip route
) 的主表:
default via {gateway_ip} dev wlan0 proto dhcp metric 600
10.2.0.0/24 dev other_vpn proto kernel scope link src 10.2.0.210
还有一个看起来像这样 ( ip route list table 51820
) 的“51820”表:
default dev wg0 scope link
所以当一个数据包通过这些规则和表格时:
- 在 32764,我们转到主表。
- 如果数据包要去 10.2.0.5,那么它将到达 10.2.0.0/24 路由,并且带有 24 前缀,这就是它要去的地方。
- 另一方面,如果匹配默认值 (0.0.0.0/0),则不会转到 wlan0 上的 gateway_ip,它将被 抑制
suppress_prefixlength 0
,我们将继续。
- 在 32765,我们检查 fwmark。如果它不是 0xca6c(即,它不是为实现 wg0 发送的数据包wireguard),那么我们将转到表 51820。这很简单:一切都经过 wg0。
- 如果 fwmark 是 0xca6c,因此它是一个线保护数据包,那么我们将转到 32766。这将带我们回到主表,在这种情况下,我们将匹配默认路由和线保护数据包将按照我们的意愿通过 wlan0 出去:我们最终需要使用我们的物理连接。
如果您使用ip rule
,您将看到以下输出:
0: from all lookup local
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main
32767: from all lookup default
您的问题是关于第 32764 行的,它用于通过隧道路由所有流量,而不是在 [主] 表中查找。