route 命令仅操作 main 路由表,多网卡下添加多个默认路由会相互覆盖,且回程路径强制走唯一默认网关,导致非对称路由——请求从 eth1 进、响应从 eth0 出,源 ip 与出口不匹配而被丢包,引发 ssh 断连、应用不通等问题;必须用 ip rule + ip route table 实现基于源地址的策略路由,为每张网卡配置独立路由表(含直连路由和默认路由)及 from ip/32 规则,确保出入路径一致。

route 和 ip route 都能加静态路由,但默认只走一张表(main),多网卡必须用策略路由 —— 否则会出现回包失败、SSH 断连、ping 通但应用不通等问题。
为什么 route add default gw 在多网卡下会出问题
Linux 内核默认只允许一个 default 路由条目存在于 main 表中。你执行两次 route add default gw,后一次会直接覆盖前一次,而不是并存。
更关键的是:即使你手动加了多条非默认路由(比如 route add -net 2.2.2.0/24 gw 1.1.1.254),内核仍会用 main 表里的唯一默认网关来决定**回程路径**。如果请求从 eth1 进来,但响应却从 eth0 出去,对方看到源 IP 和出口接口不匹配,大概率丢包。
- 现象:从外网能
ssh进eth1的 IP,但一执行命令就卡住或断开 - 原因:响应包走了
main表默认网关(比如配在eth0上),违反了对称路由原则 - 结论:
route命令只适合单网卡场景;多网卡必须切换到ip rule + ip route table机制
/etc/iproute2/rt_tables 必须先定义新表名
系统默认只有 local、main、default 三张表,新增路由表必须先在 /etc/iproute2/rt_tables 里注册名称和数字 ID,否则 ip route add table xxx 会报错 RTNETLINK answers: No such file or directory。
追加两行(ID 建议从 100 起,避开系统保留值):
100 tab_eth0 101 tab_eth1
注意:
- 等号左右不能有空格,格式必须是
ID name - 改完无需重启,但已有规则不会自动识别新表名,需重新加载规则
- 名字不能含下划线以外的特殊字符,
tab-eth0会失败,只能用tab_eth0
为每个网卡配置独立路由表 + 规则
假设:
-
eth0:IP192.168.10.100/24,网关192.168.10.1 -
eth1:IP10.0.20.100/24,网关10.0.20.1
执行以下命令(顺序不能错):
ip route add 192.168.10.0/24 dev eth0 src 192.168.10.100 table tab_eth0 ip route add default via 192.168.10.1 dev eth0 table tab_eth0 ip route add 10.0.20.0/24 dev eth1 src 10.0.20.100 table tab_eth1 ip route add default via 10.0.20.1 dev eth1 table tab_eth1 ip rule add from 192.168.10.100/32 table tab_eth0 ip rule add from 10.0.20.100/32 table tab_eth1
说明:
- 每张表里必须包含直连子网路由(
dev ethX)和默认路由(via),缺一不可 -
src参数强制该表内出包使用对应 IP,避免内核选错源地址 -
from IP/32是最稳妥的规则写法;用from 192.168.10.0/24有可能匹配到其他设备发来的伪造包 - 规则优先级默认递增,先加的规则 priority 数值小,匹配更早
永久生效要改三个地方,少一个都会重启失效
临时命令重启即丢。要持久化,必须同时处理:
-
路由表定义:已写入
/etc/iproute2/rt_tables,这步只需做一次 -
路由条目:写进
/etc/sysconfig/network-scripts/route-eth0和/etc/sysconfig/network-scripts/route-eth1,内容例如:192.168.10.0/24 dev eth0 src 192.168.10.100 table tab_eth0default via 192.168.10.1 dev eth0 table tab_eth0 -
规则条目:RHEL/CentOS 系统需在
/etc/sysconfig/network-scripts/ifup-post或自定义脚本中调用ip rule add;更稳妥的是写进/etc/rc.d/rc.local(确保可执行且systemctl enable rc-local)
验证是否生效:
-
ip rule show看规则是否存在 -
ip route show table tab_eth0看表内容是否完整 -
ping -I eth0 -c2 8.8.8.8和ping -I eth1 -c2 8.8.8.8分别测试出口连通性
最易忽略的是:规则和路由表虽配好了,但没配 src 导致出包源 IP 错乱,或者忘了给每张表加直连路由,结果连本地网段都 ping 不通。











