首页 > 解决方案 > 'ip -4 rule add table main suppress_prefixlength 0' 是什么意思?

问题描述

ip -4 rule add table main suppress_prefixlength 0 该命令出现在连接wireguard vpn的过程中。

标签: iptableswireguardiproute

解决方案


用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

所以当一个数据包通过这些规则和表格时:

  1. 在 32764,我们转到主表。
    1. 如果数据包要去 10.2.0.5,那么它将到达 10.2.0.0/24 路由​​,并且带有 24 前缀,这就是它要去的地方。
    2. 另一方面,如果匹配默认值 (0.0.0.0/0),则不会转到 wlan0 上的 gateway_ip,它将被 抑制suppress_prefixlength 0,我们将继续。
  2. 在 32765,我们检查 fwmark。如果它不是 0xca6c(即,它不是为实现 wg0 发送的数据包wireguard),那么我们将转到表 51820。这很简单:一切都经过 wg0。
  3. 如果 fwmark 是 0xca6c,因此它一个线保护数据包,那么我们将转到 32766。这将带我们回到主表,在这种情况下,我们将匹配默认路由和线保护数据包将按照我们的意愿通过 wlan0 出去:我们最终需要使用我们的物理连接。

推荐阅读