登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

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/32ip 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 表执行。

源地址、策略规则优先级、自定义路由表和主路由表的静态关系图
图 1:从“匹配条件”“RPDB 规则”“路由表”三个分组查看源地址与表 100 的绑定关系;数字越小优先级越高,这是静态结构图,不是系统命令截图。

三、在独立表中补齐直连路由和默认路由

只向表 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 选择器,两者角色不同。

策略路由表中的直连路由、默认路由、网关和出口接口依赖关系图
图 2:表 100 同时依赖直连网段与默认路由;直连路由负责网关可达,默认路由负责其他目标,这是静态依赖图,不是网络工具截图。

四、添加 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 核对内核选择,最后补上回滚、反向路径与持久化方案。规则、路由表和回程检查三者缺一不可。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>