ip-rule配合多路由表实现基于源/目的IP、TOS或fwmark等条件的流量分流,rule仅决定查哪张表,路由路径由对应table中的route条目确定。

Linux 的 ip-rule 配合多路由表,是实现基于源地址、目标地址、TOS 或 fwmark 等条件进行流量分流的核心机制。它不替代默认路由,而是为不同流量“选择”合适的路由表,从而让特定 IP(如某业务服务器、某出口网段)走指定网关或接口。
理解:rule + table 才构成完整路由决策链
Linux 内核默认只用 main 表(table 254),而 ip rule 定义了“什么情况下查哪张表”。每条 rule 匹配成功后,就跳转到对应 table 查找路由。没有显式 rule 指向的表,永远不会被查到。
- rule 本身不定义路径,只做“分发判决”;真正决定下一跳的是路由表里的
ip route条目 - rule 有优先级(priority),数值越小越先匹配;冲突时以第一条匹配为准
- 常用匹配字段包括:
from(源IP)、to(目的IP)、fwmark(配合 iptables 标记)、tos、iif/oif(入/出接口)等
实操:为 192.168.10.100 的出向流量指定独立出口
假设 eth0 连主网(默认网关 192.168.1.1),eth1 连专线网段(网关 10.0.100.1),希望从 192.10.100.100 发出的所有包都走 eth1:
- 创建自定义路由表,例如在
/etc/iproute2/rt_tables中追加:100 special_out - 为该表添加路由:
ip route add default via 10.0.100.1 dev eth1 table special_out - 添加 rule,使源为 192.168.10.100 的包查这张表:
ip rule add from 192.168.10.100/32 table special_out - 验证:执行
ip rule show和ip route show table special_out,再用ip route get from 192.168.10.100 to 8.8.8.8看实际选路
注意:回程路径必须对称,否则连接失败
仅配置出向分流还不够。若响应包仍按默认路由返回(比如从 eth0 回),就会出现“请求走 eth1、响应走 eth0”的非对称路径,多数防火墙和中间设备会丢弃此类包。
- 确保对端能正确路由回包:要么专线侧配置静态路由指向 192.168.10.100,要么在本机为该 IP 添加反向 rule(如
ip rule add to 192.168.10.100/32 table special_out)并补全回程路由 - 更稳妥的做法是:在
special_out表中同时配置目的网络的直连路由(如192.168.10.0/24 dev eth1 scope link)和默认路由,避免依赖 main 表 - 测试时用
tcpdump -i eth1 host 8.8.8.8抓包确认双向流量是否真走同一接口
进阶:结合 iptables + fwmark 实现应用级分流
当需按端口、协议或用户 UID 分流(如让某 Docker 容器或某用户进程走专线),单靠 IP 地址不够,此时用 iptables 标记数据包,再由 rule 转发至对应路由表:
- 标记来自某用户的 TCP 流量:
iptables -t mangle -A OUTPUT -m owner --uid-owner appuser -p tcp -j MARK --set-mark 100 - 添加 rule 响应 mark:
ip rule add fwmark 100 table special_out - 注意:OUTPUT 链标记仅影响本机发出的包;若要标记转发流量,需用 FORWARD 链 + 对应的 in/out 接口条件
- mark 值是整数,建议与 table ID 保持一致便于维护,且需确保未被其他模块占用(如 conntrack、tc)











