必须配合ip rule与ip route实现策略路由:为每网卡创建独立路由表并绑定源ip,再通过规则指定查表路径,同时关闭rp_filter和开启转发,否则将因反向路径过滤或路由冲突导致跨网卡通信失败。

ip rule 和 ip route 配合使用才能让多网卡真正“指哪走哪”,只配默认路由或只加静态路由根本解决不了源出不一致、回包丢弃、跨网卡通信失败这些问题。
为什么单靠 route add default 会失效
Linux 内核默认只用 main 路由表,所有网卡的流量都走同一张表。当你给 eth0 和 eth1 各配一个默认网关,系统只会保留最后添加的那个,前一个被覆盖;更关键的是,响应包可能从另一张网卡发出(比如请求从 eth0 出,响应却从 eth1 回),触发反向路径过滤(rp_filter)直接丢包。
- 现象:
ping -I eth0_ip target成功,但外部 ping 该 IP 失败;或 SSH 连上后立即断开 - 本质:入向和出向接口不匹配,违反了对称路由原则
- 必须同时满足三个条件:开启转发、关闭
rp_filter、按源地址绑定独立路由表
配置自定义路由表并绑定源地址
核心是把每块网卡的 IP 和它的网关“锁死”在一张专属路由表里,再用规则告诉内核:“凡是这个源 IP 发出的包,查这张表”。
- 先编辑
/etc/iproute2/rt_tables,追加两行(编号建议 100–252):100 table_eth0101 table_eth1 - 为
table_eth0添加直连网段 + 默认路由(假设 eth0 地址 192.168.1.100/24,网关 192.168.1.1):ip route add 192.168.1.0/24 dev eth0 src 192.168.1.100 table table_eth0ip route add default via 192.168.1.1 dev eth0 table table_eth0 - 同理配置
table_eth1(假设 eth1 地址 10.0.2.100/24,网关 10.0.2.1):ip route add 10.0.2.0/24 dev eth1 src 10.0.2.100 table table_eth1ip route add default via 10.0.2.1 dev eth1 table table_eth1 - 最后加策略规则(顺序很重要,优先级数字越小越先匹配):
ip rule add from 192.168.1.100/32 table table_eth0 priority 100ip rule add from 10.0.2.100/32 table table_eth1 priority 101
必须关闭 rp_filter 否则策略路由形同虚设
即使路由表和规则全对,只要 rp_filter 开着,内核就会检查“响应包是否能通过原路径返回”。而策略路由下,响应包走的是另一张表,大概率被判定为“非对称”而丢弃。
- 临时关闭(验证用):
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filterecho 0 > /proc/sys/net/ipv4/conf/eth0/rp_filterecho 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter - 永久生效:在
/etc/sysctl.conf中添加net.ipv4.conf.all.rp_filter = 0net.ipv4.ip_forward = 1
然后执行sysctl -p - 注意:
rp_filter = 1(严格模式)和= 2(松散模式)都不够用,必须设为0
如何验证策略路由是否生效
别只看 ip route show,它默认只显示 main 表;也别只测 ping,得逐层确认每个环节。
- 查规则是否加载:
ip rule show,确认输出里有你加的from xxx table xxx条目,且 priority 值符合预期 - 查指定表内容:
ip route show table table_eth0、ip route show table table_eth1,确保含直连网段和默认路由 - 模拟源地址发包测试:
ping -I 192.168.1.100 8.8.8.8,同时用tcpdump -i eth0 icmp看是否真从 eth0 出;换-I 10.0.2.100测试 eth1 - 最容易忽略的一点:如果网卡没配置好 IP 或 link down,
ip route add dev eth0会静默失败,务必先ip addr show eth0确认状态为UP且有正确地址











