系统上有 VRF、定义的多个路由表和规则。本地服务 (SSH) 无法通过一个接口(VRF 中的 WAN 接口)访问,但可以从其他接口访问。数据包过滤器已禁用。
我想调试到底是哪里卡住了。
VRF和IP规则同时定义,到底是如何决定路由的?
作为一个例子,在没有 VRF 的情况下:
# ip rule show
101: from all lookup local
102: from all lookup main
103: from all lookup vrf_wan
170: from all fwmark 0x800000a9 lookup vrf_wan
254: from all fwmark 0x800000fd lookup main
1000: from all lookup [l3mdev-table]
2000: from all lookup [l3mdev-table] unreachable
32765: from all lookup local
32766: from all lookup main
32767: from all lookup default
内核将从最低规则开始。如果规则与源、目标或 fwmark 匹配,它将在表中查找。如果存在匹配的条目,则该过程停止并选择路由。如果表不包含匹配条目,则处理下一条规则,依此类推(如果我对此有误,请纠正我)。
如果有一个 VRF 分配给特定接口和/或进程,现在该怎么办?这是完全正交的吗ip rule show
?我需要在它们之间进行选择吗?或者两者可以同时使用吗?
评论: 我的系统是VyOS。规则 1000、2000、32765-32767 由 VyOS 生成,无法删除。规则 170 和 254 也是由 VyOS 中的策略规则生成的,但被我的其他策略(规则 101-103)覆盖。
答案1
默认情况下,VRF 有一个优先级为 1000 的关联路由规则,如VRF 文档如下就像 OP 的例子那样:
- l3mdev FIB 规则将查找定向到与设备关联的表。单个 l3mdev 规则足以满足所有 VRF。当第一个设备处于 VRF 状态时,VRF 设备会添加针对 IPv4 和 IPv6 的 l3mdev 规则使用默认首选项 1000 创建。用户可以如果需要,请删除规则并添加不同的优先级或安装每个 VRF 规则。
因此,您可以删除优先级 1000 的规则并创建手动规则,或者只是调整您自己的规则:根据需要 pref < 1000 或 pref > 1000,就像您所做的那样。
有关 VRF 的更多信息可以在此博客中找到: Stefan 的博客在 Linux 上使用 VRF(虚拟路由和转发),包括为什么 VyOS 创建规则 pref 2000 以及为什么本地表查找从 pref 0 移动到 pref 32765。
更新:解决OP的问题评论。
什么是ip vrf exec blue ...
?它设置了一个强制套接字选项的 BPF 过滤器每当受影响的进程创建套接字时:
[...]
BPF 过滤器附加到 vrf/NAME cgroup2 以将 sk_bound_dev_if 设置为 VRF 设备索引。 [...] 这样做时,所有 AF_INET/AF_INET6 (ipv4/ipv6) 套接字都会自动绑定到 VRF 域。
我知道它相当于使用 VRF 感知的进程setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "vrf-blue", ...)
。
这意味着oif
规则或我所理解的l3mdev
规则将由此专门选择(如果它们在之前解析路由之前使用),否则只有与设备匹配的剩余路由才会匹配。
(也根据经验(VRF 之外)我知道,当绑定到接口时,如果没有目的地的路由,它的行为就像添加了一条路由以便能够在绑定时发出数据包,但该路由不会有任何网关所以很少能正常工作)。
请注意,这更容易理解在内核 4.8 之前,人们必须系统地做:
在 v4.8 内核之前,每个 VRF 设备都需要 iif 和 oif 规则:
ip ru add oif vrf-blue table 10 ip ru add iif vrf-blue table 10
如果尝试使用标准规则(不带)oif
来短路 pref 1000 中的规则,则该规则将发挥作用。l3mdev