Linux 策略路由怎么按源地址选择路由表
来源:17golang原创
时间:2026-10-06 13:04:27 181浏览 收藏
Linux 按源地址选择路由表,核心是两部分:先在独立表里写好可用路由,再添加 ip rule add from 源前缀 priority 优先级 lookup 表号。规则只负责“选哪张表”,真正的出口接口、网关和首选源地址仍由被选中的路由表决定。
ip rule 官方手册:https://man7.org/linux/man-pages/man8/ip-rule.8.html
下面用文档保留地址演示:接口 eth1 上有 192.0.2.10/24,网关是 192.0.2.1,希望源地址为 192.0.2.10 的流量查询路由表 100。这些地址只是示例,执行前必须替换成主机的真实网络参数,并保留备用管理会话。
一、先确认什么流量需要按源地址分流
普通路由主要根据目标地址查表。策略路由引入 RPDB(Routing Policy Database),可以根据源地址、目标地址、入站接口、fwmark 等条件选择不同路由表。本例只使用 from,避免把标记、端口或接口规则混在一起。
| 项目 | 示例值 | 用途 |
|---|---|---|
| 源地址 | 192.0.2.10/32 | ip rule 的匹配条件 |
| 出口接口 | eth1 | 自定义表中的出接口 |
| 直连网段 | 192.0.2.0/24 | 让表 100 能到达网关 |
| 网关 | 192.0.2.1 | 表 100 的默认下一跳 |
| 路由表 | 100 | 与 main 表隔离的策略表 |
| 规则优先级 | 100 | 位于 local 与 main 默认规则之间 |
from 192.0.2.10/32 匹配的是已经带有该源地址的数据包,它不会强制所有应用都使用这个地址。应用绑定了其他源地址时不会命中;未绑定源地址的本地连接,还要结合接口地址、路由中的 src 首选值和应用行为判断。
二、检查现有地址、规则和主路由表
变更前先保存基线。重点看接口是否真的拥有该源地址、规则优先级是否已占用,以及 main 表里当前默认出口是什么。
# 确认 eth1 上存在计划用于匹配的 IPv4 地址。 ip -4 addr show dev eth1 # 查看 RPDB;数字越小,规则优先级越高。 ip -4 rule show # 保存主路由表和目标策略表的变更前状态。 ip -4 route show table main ip -4 route show table 100
Linux 默认通常有三条 RPDB 规则:优先级 0 查询 local 表,32766 查询 main 表,32767 查询 default 表。自定义规则使用明确且唯一的优先级,例如 100,能让它在保留 local 表的同时早于 main 表执行。

三、在独立表中补齐直连路由和默认路由
只向表 100 添加默认路由经常会遇到“网关不可达”,因为自定义表未必拥有 main 表中的直连路由。稳妥做法是先添加出口网段,再添加默认路由。
# 直连路由让表 100 能解析位于同一二层网段的网关。 sudo ip route replace 192.0.2.0/24 dev eth1 \ src 192.0.2.10 table 100 # 默认路由把其他目标交给 192.0.2.1,并从 eth1 发出。 sudo ip route replace default via 192.0.2.1 \ dev eth1 table 100 # 复查表 100,确认直连网段和默认路由同时存在。 ip -4 route show table 100
路由里的 src 192.0.2.10 是该路径建议使用的首选源地址,不等于 ip rule from 的匹配条件。前者属于路由属性,后者属于 RPDB 选择器,两者角色不同。

四、添加 from 规则并设置唯一优先级
表内路由准备好后,再添加源地址规则。把规则放在最后可以避免“规则先命中、表却还没有可用路径”的短暂故障窗口。
# 仅匹配源地址 192.0.2.10,并查询路由表 100。 sudo ip rule add priority 100 \ from 192.0.2.10/32 lookup 100 # 精确查看新增规则,避免重复添加相同优先级或选择器。 ip -4 rule show priority 100
规则按优先级数字从小到大处理。每条规则最好使用唯一、显式的优先级,避免依赖工具自动分配。若表 100 对某个目标没有可用路由,查找可以继续到后续规则;但如果表中配置了 unreachable、prohibit 或 blackhole 等终止类型,行为会不同。
五、用 ip route get 验证查表结果
不要只看 ip rule show 就判断成功。ip route get 可以带上测试源地址,直接查看内核针对这组源、目标条件会选择哪张表、哪个网关和哪个接口。
# 用文档保留目标地址验证源地址规则,不发送真实业务流量。 ip -4 route get 203.0.113.20 \ from 192.0.2.10 # 对照目标表,确认所选路径确实来自表 100。 ip -4 route show table 100
预期结果应包含 via 192.0.2.1、dev eth1、table 100 和 src 192.0.2.10 等关键字段。若缺少 table 100,先检查测试命令的 from 是否与规则前缀一致,再检查优先级前面是否有更早命中的规则。
应用层验证时,要确保测试程序确实绑定或使用了 192.0.2.10。策略规则是按数据包字段匹配,而不是按“希望从哪张网卡出去”的意图猜测。
六、准备无损回滚路径
回滚时先删除规则,使新流量恢复查询 main 表,再清理自定义表。若先清空表 100 而保留规则,会留下一个仍可命中却没有目标路径的中间状态。
# 先移除源地址规则,让流量回到后续 RPDB 规则。 sudo ip rule del priority 100 \ from 192.0.2.10/32 lookup 100 # 再清理仅用于本方案的表 100;执行前确认没有其他规则共用它。 sudo ip route flush table 100 # 复查规则和表,确认策略项已撤销。 ip -4 rule show ip -4 route show table 100
远程主机上应在改动前准备备用 SSH 会话、控制台或带外管理通道。表号 100 如果已被其他业务使用,不要 flush 整张表,而应按具体前缀逐条删除本次新增路由。
七、处理反向路径过滤和持久化
策略路由常用于多网卡或非对称路径。此时出站方向正确,回包却可能被反向路径过滤丢弃。内核文档中,rp_filter=1 是严格模式:如果入站接口不是到数据包源地址的最佳反向路径,检查会失败;复杂或非对称路由场景通常需要评估松散模式 2。
# 查看全局和接口级反向路径过滤;实际取 all 与接口配置中的较大值。 sysctl net.ipv4.conf.all.rp_filter sysctl net.ipv4.conf.eth1.rp_filter # 只展示临时调整示例;生产变更前应评估反欺骗风险与发行版持久化方式。 sudo sysctl -w net.ipv4.conf.eth1.rp_filter=2
不要为了“先通再说”直接把过滤全部关闭。严格模式有助于防止源地址欺骗;只有确认网络确实是非对称设计,并完成安全评估后,才按接口采用松散模式或其他适配方案。
ip route 和 ip rule 命令直接修改的是运行时状态,重启或网络服务重载后可能丢失。持久化应交给当前发行版实际使用的网络管理器,例如 NetworkManager、systemd-networkd 或发行版网络配置系统,并保持同样的表号、优先级、源前缀、直连路由与默认路由。不要同时让多个管理器重复下发。
八、复盘策略路由常见故障
- 规则命中错误:用
ip route get 目标 from 源地址验证,不要只看规则是否存在。 - 网关不可达:检查自定义表是否包含到网关所在网段的直连路由。
- 优先级冲突:每条规则使用唯一优先级;数字越小越早匹配。
- 源地址不匹配:确认应用真实使用的源地址与
from前缀一致。 - 回包被丢弃:检查回程路由、防火墙和
rp_filter,不要只盯着出站表。 - 重启后失效:将规则和路由写入唯一的网络管理系统,避免多个服务互相覆盖。
- 回滚影响其他业务:清表前确认表号没有被其他规则或 VRF 共用。
只加 ip rule,不加 table 100 的路由可以吗?
规则本身不提供下一跳,只指定查询哪张表。如果目标表为空或缺少可用路由,结果可能继续落到后续规则,也可能因为表中终止路由而失败,无法达到固定出口的目的。
from 应该写 /32 还是网段?
只分流单个本机地址时用 /32 更精确;需要让整个源网段共用策略时再写网段前缀。范围越大,影响面越大,变更前应逐个确认其中地址是否都应该走同一张表。
为什么规则存在,但程序还是走 main 表?
常见原因是程序实际使用了另一个源地址,或者有更高优先级规则先命中。先用 ip route get 带 from 模拟,再检查应用绑定地址和完整 RPDB 顺序,通常比反复删除重加规则更快。
按源地址策略路由的稳定做法可以概括为:先建立完整自定义表,再添加唯一优先级的 from 规则,用 ip route get 核对内核选择,最后补上回滚、反向路径与持久化方案。规则、路由表和回程检查三者缺一不可。
-
106 收藏
-
411 收藏
-
209 收藏
-
312 收藏
-
441 收藏
-
439 收藏
-
321 收藏
-
294 收藏
-
233 收藏
-
166 收藏
-
426 收藏
-
243 收藏
-
132 收藏
-
395 收藏
-
231 收藏
-
470 收藏
-
306 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习