使“ip 规则”的优先级高于“本地”

Coo*_*ops 6 networking linux routing linux-networking

我正在尝试使用 fwmarks 将传入流量的一部分重定向到不同的目的地。

步骤

1) 标记匹配的传入数据包:

iptables -t mangle -A PREROUTING -i pppoe0 -p tcp -m tcp --dport 80 -j MARK --set-xmark 6

2) 添加一条规则,将标记的数据包定向到路由表“200”。

ip rule add fwmark 6 table 200

3) 在路由表“200”上添加一条到新目的地的默认路由。

ip route all default via 192.168.33.2 table 200

问题

iptables -L PREROUTING -t mangle -v显示与我在步骤 1 中制定的规则相匹配的数据包,但它们从未转发到我期望的位置。

我认为问题在于流量的目的地被认为是主机本地的地址,并且localip 规则与我在步骤 2 中添加的规则相匹配,例如

~# ip rule show
0:      from all lookup local   <--- taking priority...
32765:  from all fwmark 0x6 lookup 200   <--- ... over this.
32766:  from all lookup main
32767:  from all lookup default
Run Code Online (Sandbox Code Playgroud)

问题:有没有办法让我的规则优先于其他local规则?

A.B*_*A.B 4

preference您可以使用(orprio或etc.) 关键字指定规则优先级pref,以覆盖为规则选择的默认优先级(通常是“低于不等于 0 的最低优先级”)。

您还可以创建一个重复其他规则但使用不同优先级的规则,然后删除具有其他优先级的原始规则:这相当于更改规则的优先级。

您可以在这里执行以下操作:

ip rule add preference 200 fwmark 0x6 lookup 200
ip rule add preference 300 lookup local
ip rule delete preference 0
Run Code Online (Sandbox Code Playgroud)

这会将查找本地路由表的规则从 0 移动到 300,为其他规则的优先级留出空间,例如现在优先级为 200 的规则。此顺序可防止任何连接丢失(假设路由表 200 不会造成任何丢失)连接本身)。


SU 上的示例,我在回答通常用于没有 NAT 或 fwmark 的本地系统的路由(和隧道)流量时使用了此示例:

使用 Wireguard 从本质上为本地网络中的计算机提供来自 VPS 的公共地址


为此避免使用iptables通常是让它正常工作的最佳方法。这需要内核 >= 4.17

扩展 fib 规则匹配支持以包括 sport、dport 和 ip proto 匹配(以完成 5 元组匹配支持)。数据中心中基于策略的路由的常见用例需要 5 元组匹配

如果没有iptables标记,这看起来像:

ip rule add preference 200 iif pppoe0 ipproto tcp dport 80 lookup 200
Run Code Online (Sandbox Code Playgroud)

再加上相反的方向,根据问题可能是其他接口,或者在某些情况下iif lo是表示本地启动的特殊单词:

ip rule add preference 201 iif ... ipproto tcp sport 80 lookup 200
Run Code Online (Sandbox Code Playgroud)

我无法给出完整的答案,因为涉及很多因素,这取决于最终目标,这里不是很清楚(你可以看一下我的 SU 答案,看看所有可能出错和需要更改的地方,就像某些情况下的 ARP)。