策略路由与分流规则

普通路由只看目的地址决定下一跳,策略路由(PBR,Policy-Based Routing)在此基础上加入了源地址、入接口、协议、标记等判断条件,让不同流量走不同出口。家里的 IPTV 必须走电信线、书房设备固定走移动线、内网网段直连不走默认网关,这些需求都要靠它实现。本篇讲策略路由的原理、在 OpenWrt 上的原生实现,以及 PBR 插件这个高级工具。

路由表与规则的关系

Linux 的策略路由由两张表协同工作:路由表记录怎么走,策略规则决定用哪张表。系统默认有一张 main 表(平时看到的默认路由就在这里),你可以创建额外的自定义表,再用 ip rule 规则把特定流量指过去。路由表的数字编号和别名在 /etc/iproute2/rt_tables 文件里定义,LuCI 界面下拉框里看到的那些表名就是这个文件的产物。

# 查看所有策略规则
ip rule show

# 查看自定义表的路由
ip route show table 100

ip rule show 的输出从上到下按优先级排列,匹配即停止。默认的 main 表优先级 32766,你新加的规则优先级设得比它小,就会先被匹配到。这条优先级机制是排障的关键:规则不生效时,先查优先级更高的规则有没有把它截胡。

举个每个人都会遇到的真实需求帮助理解。家里同时有两条宽带、一台 IPTV 盒子、一台下载机、若干手机电脑。普通路由只回答一个问题:这个包要发给谁?策略路由回答的是三个问题:谁发的、要给谁、走哪条路。于是你能规定:盒子只走电信线(组播源都在电信网内)、下载机只走移动线(不影响主线的游戏延迟)、其它流量两条线负载均衡。普通路由表根本表达不了这种逻辑,这就是策略路由存在的理由。

OpenWrt 贴心地在 UCI 里封装了原生写法,Network → Routing → Rules 页面可以直接添加,不用手敲 ip 命令。一个最典型的分流规则如下配置:来自 192.168.1.50(书房电脑)的流量,查表 100,表 100 的默认网关是 WAN2:

config rule
    option src '192.168.1.50/32'
    option lookup '100'

config route
    option interface 'wan2'
    option target '0.0.0.0/0'
    option table '100'

这两段配合,就把书房设备固定分流到了 WAN2。条件字段非常丰富,常用的有下面几个。除表里列的之外,高级用户还会组合 invert 字段做反向匹配(比如除了某个 IP 段之外全部命中),或用 priority 精确控制规则的先后。够用就好,一个规则只表达一个意图,是长期维护的秘诀。

字段 作用 示例
src 匹配源地址段 192.168.1.0/24
dest 匹配目的地址段 10.0.0.0/8
in 匹配入接口 lan
mark 匹配防火墙标记 0x1
lookup 使用的路由表 100
action 路由动作 prohibit/blackhole

用 UCI 实现三个典型分流

场景一:内网直连。访问公司内网网段 10.1.0.0/16 时不要走默认网关出公网,直接从内网接口出去。写一条规则 dest 填网段、lookup 指向包含公司网关路由的表即可,OpenWrt 内置内网网段的直连规则通常已覆盖,只有跨设备转发时才需要手动补。

场景二:按设备分流。家里的电视盒子必须走电信线(IPTV 才不卡),其它设备默认均衡。在 mwan3 的规则里按源地址指定策略,或者写上面演示的自定义表规则,都能实现。这类需求的本质是 多 WAN 流量调度 的一部分,和上一章的负载均衡配置一脉相承。按设备分流的规则优先级一定要高于通用规则,而且建议绑定固定 IP 或做地址保留,避免 DHCP 分配变化后规则失效。很多新手的规则没生效,最后发现是目标设备的 IP 变了,匹配条件早就不指向它。

场景三:按服务分流。网页流量走主线、下载机走备线,避免下载挤占游戏带宽。以源地址加目的端口组合作为匹配条件,比单纯按 IP 分流更灵活。配合防火墙的 mangle 标记,还能实现按连接类型分流,规则持久且不随 IP 变化而失效。做服务级分流时先把常见服务的端口整理清楚:网页是 80 和 443、游戏各有专属端口、视频会议以 UDP 为主。整理过程本身也是一次家庭网络的梳理,做完之后你对家里流量构成的了解会上一个台阶。

策略路由匹配过程

PBR 插件:更高层的抽象

原生写法灵活但学习曲线陡,OpenWrt 社区的 PBR(pbr 包,前身 vpn-policy-routing)把策略路由封装成了按域名、按进程、按 IP 段的规则列表:

# 安装并启用 PBR
opkg update
opkg install pbr luci-app-pbr

# 添加策略:局域网某网段走指定接口
uci add pbr policy
uci set pbr.@policy[-1].src_addr='192.168.1.0/24'
uci set pbr.@policy[-1].interface='wan2'
uci commit pbr
service pbr restart

PBR 的优势是规则集中、自动处理路由表和标记的创建、配置界面友好。它还内置域名解析为 IP 段的能力,写域名的规则在域名解析变化时自动更新,这是手写 ip 规则做不到的。此外 PBR 支持 nftables/iptables 双后端、规则可批量启停、带 Web 界面的状态显示,对于不想学习 ip route 细节又需要灵活分流的用户,是当下最推荐的工具。

安装时的一个细节提醒:新版固件里包名是 pbr,旧版叫 vpn-policy-routing,两者界面和配置不通用,安装前先 opkg list 看看你的源里是哪个。两个包不要同时安装,冲突起来整个分流体系都会失效。

使用 PBR 有两个注意点。其一,它与 mwan3 都用防火墙标记,同时开启可能互相干扰,简单场景二选一,复杂需求再研究共存配置。其二,PBR 的默认产生高于 main 表的规则,配错可能整体断网,改完先用 mwan3 status 类的命令确认连通再大规模应用。关于标记机制的底层原理, 防火墙与流量标记 一章有更系统的说明。

调试与排障

调试与排障的核心动作就两条:先看清包实际走了哪里,再确认回包怎么回来。养成这个双向思维,策略路由的绝大多数疑难杂症都能自己消化。

策略路由不生效时,按这三步走。

第一步定位包实际走了哪条规则:ip rule show 看规则顺序,tcpdump 在出口接口抓包确认包有没有从预期接口出去。第二步检查表内容:ip route show table 100 看目标表里有没有默认路由,空表配置再漂亮也不转。第三步确认返回路径:分流过去之后回包怎么回来,很多疑难杂症是回来时被另一条规则劫持了。

原生策略路由与PBR插件;原生写法细粒度完全可控;PBR插件上手段少易学,与mwan3可能冲突

还有一类高频故障:配了策略之后部分网站打不开、换一个就好。八成是规则把 DNS 流量也分流了,导致解析走了不同线路出问题。稳妥的做法是规则匹配条件里把 DNS 服务器的 IP 排除,或确保 DNS 走稳定线路。

配套的网络知识

策略路由调试到深处会遇到一个绕不开的问题:规则越写越多怎么管。经验是按用途分组、按优先级排序。把网络以日常使用排个序:内网直连优先级最高(不能出错否则连路由器都摸不到),其次是外部固定出口规则(电视盒子一类刚需),再次才是各种优化类细分规则,默认均衡兜底。每次新增规则前自问一句:这条规则如果整体失效,家里的网还能不能用,答案肯定才动手。

另一点是新旧规则共存时先验证再启用。OpenWrt 的 LuCI 允许保存不应用,利用这个缓冲期 ip route show 核对生成的表项是否符合预期,确认无误再点应用。养成这个习惯可以避开九成灾难性配置事故。这些方法论与 网络运维实践 中讲的变更管理是同一套思维框架,值得日常坚持。

最后给一个落地建议:策略路由配置达到七八条以上时,强烈建议在 /etc/config/network 加注释段落把规则意图写清楚,几个月后回来看自己都记不清当时为什么这么写的。多人共用网络的家庭,注释也是交接文档,能避免后来者误删关键规则导致全家断网。

延伸阅读

  • 《多 WAN 与负载均衡》:mwan3 的完整配置,与本篇的策略规则互为补充。
  • 《SQM 与智能队列限速》:分流解决的是走哪条路的问题,限速解决的是路有多宽的问题。
  • 《系统日志与监控》:策略路由调不顺时,日志和抓包是最好的 witnesses。