ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

路由策略实验:OSPF路由过滤与属性改写全解析

路由策略实验:OSPF路由过滤与属性改写全解析

路由策略实验,说白了就是让路由器按照你定好的规则去学习路由、发布路由、甚至改写路由的路由属性。这个实验我做过很多遍,也带过不少刚接触网络的同事做过。很多人一上来就盯着命令敲,敲完发现路由表还是乱七八糟,该过滤的没过滤,该走某条链路的流量却绕了远路。问题基本不在命令本身,而在没把“策略生效点”和“匹配顺序”这两件事想清楚。

这篇东西会围绕一个典型实验展开:用几台路由器搭一个多区域网络,通过过滤列表、route-map、路由打标等方式,控制路由的学习与发布,让设备按业务意图自动去选路。我会把实验场景怎么设计、底层怎么搭、策略写在哪、怎么验证、又踩过哪些坑,一步步讲清楚。适合刚学完路由协议想进阶的,或者准备网络认证考试的朋友,也适合那些打算梳理现网路由表、想控制路由扩散的同行参考。

1. 实验场景与整体思路:先搞清楚路由策略要解决什么

很多人会把“路由策略”和“策略路由”搞混,这是第一个要澄清的点。

1.1 路由策略到底在控制什么

路由策略控制的对象是“路由表怎么生成”,它工作在控制平面上。比如某个网段允不允许进路由表、以多大优先级进路由表、带着什么标签进路由表,这些都是路由策略说了算。

策略路由则不一样,它工作在转发平面上,直接决定某个数据包从哪个接口出去。实验里如果你看到set next-hop这种动作,那已经属于策略路由了。本文的“路由策略实验”,重点还是放在控制路由的学习、发布和重分布上。

路由策略的生效点通常有四个:

  • 路由接收方向:路由器从邻居收到路由时,过滤或修改属性。
  • 路由发布方向:路由器向邻居发送路由时,过滤或修改属性。
  • 路由重分布:把路由从一种协议导进另一种协议时,做匹配与改写。
  • 路由聚合/宣告:在汇总路由时对明细路由进行筛选。

常用的工具包括访问控制列表(ACL)、前缀列表、route-map(路由映射)以及路由标记(tag)。它们各管一摊:ACL和前缀列表偏向“过滤”,route-map偏向“过滤+改写”,tag则是给路由打一个持续保留的“备注符”,方便在不同的协议之间传递信息。

1.2 实验需求拆解:从一个“网络很乱”的场景说起

我模拟的环境是这样的:某企业内部网络,R1是核心路由器,R2和R3是两个分支区域的接入路由器,R4模拟外部区域或数据中心。R1和R2、R3之间跑OSPF,R1和R4之间用静态路由模拟一条外部链路,R1把从R4学到的这些外部路由重分布进OSPF,让两个分支都能访问外部网段。

这种结构很常见,也是最容易出问题的地方。实验里我设定了三个需求:

  1. 分支2的R2不关心某个外部网段,不希望它的路由表里出现这条明细。如果全网广播,只会白白占内存、占转发资源。
  2. 分支3的R3访问某一批外部网段时,希望它感觉这条路“很远”,从而在有多条路径的情况下自动选择另一条链路。这就是通过修改路由度量实现选路控制。
  3. R4来的路由在重分布进OSPF后,需要带上一个标记,方便R3侧按标记做统一策略,而不是一条条去匹配网段。

这三个需求分别对应路由过滤、路由属性改写、路由打标,正好覆盖了路由策略最核心的应用面。

1.3 为什么先把实验做在模拟环境里

我始终建议先在模拟环境或实验机柜里把行为摸透,再考虑上生产。路由策略有个特点:它改的是“看不见的路由属性”,而配置完成后,网络不会立刻报错,只会悄悄出现路由缺失、环路、或者路径不符合预期。在实验环境里你可以随时reset路由进程、反复抓路由表对比,甚至直接把配置清空重来,这在生产线上是不可想象的。

在做这个实验前,也建议给自己定一条底线:底层协议必须干干净净。也就是先把接口和OSPF全部搭好,确认路由表全通、没有手工策略干扰,再逐层叠加路由策略。最怕的就是底层本来就有问题,然后你又在上面叠了一堆策略,最后排查时根本分不清是协议没收敛还是策略引起的。

2. 环境准备与基础配置:把底层跑通了再谈策略

路由策略实验的难点不在配置本身,而在“基准是否干净”。所以环境这一块别偷懒。

2.1 环境选型:真实设备还是网络模拟环境

做这个实验,可以用真实路由器、网络模拟环境或者虚拟化平台。三者各有取舍:

我用得最多的是网络模拟环境,原因很实在:可以随时保存快照,改坏了直接回退,还能同时开多个窗口观察路由表。缺点是部分硬件转发特性、特殊接口行为和真实设备有差异,比如某些过滤动作在模拟环境里能生效,但在某些硬件上是先查转发表后查路由表的,表现会不一样。

如果你在真实设备上做实验,记得把配置文件备份好,每完成一个步骤就验证一次。真机上最忌讳一上来就堆一大段策略命令,然后一次性提交。

2.2 地址与协议规划

为了让实验清晰可查,我规划的网段全部采用有规律的地址。设备之间的互联用/30,业务网段用/24,外部网段用/16或/24,方便一眼看出路由的来龙去脉。

设备接口地址说明
R1接口连R210.0.1.1/30OSPF 互联
R2接口连R110.0.1.2/30OSPF 互联
R1接口连R310.0.2.1/30OSPF 互联
R3接口连R110.0.2.2/30OSPF 互联
R1接口连R410.0.3.1/30外部链路
R4接口连R110.0.3.2/30外部设备
R2业务网段192.168.10.0/24分支2内网
R3业务网段192.168.20.0/24分支3内网
R4对外网段172.16.10.0/24外部网段A
R4对外网段172.16.20.0/24外部网段B
R4对外网段10.10.0.0/16外部网段C

OSPF进程跑在10.0.1.0/24、10.0.2.0/24这些互联网段上,区域用area 0。R1在OSPF里通告自己的互联和回环网段,同时把到R4的静态路由或直连路由重分布进OSPF。

2.3 基础配置:先把OSPF跑起来

以常见企业路由器命令行风格为例,接口配置大概是这个样子:

interface GE0/0 ip address 10.0.1.1 255.255.255.252

R1上配置OSPF:

router ospf 1 network 10.0.1.0 0.0.0.3 area 0 network 10.0.2.0 0.0.0.3 area 0 network 10.0.3.0 0.0.0.3 area 0

R2和R3只把自己连接R1的接口和业务网段宣告进OSPF:

router ospf 1 network 10.0.1.0 0.0.0.3 area 0 network 192.168.10.0 0.0.0.255 area 0

R4不跑OSPF,它只需要有到R1及外部网段的直连和静态路由。R1上配置一条指向外部网段的静态路由,然后重分布进OSPF:

ip route 172.16.10.0 255.255.255.0 10.0.3.2 ip route 172.16.20.0 255.255.255.0 10.0.3.2 ip route 10.10.0.0 255.255.0.0 10.0.3.2

这时R2和R3应该能看到这些外部路由。先别急着加策略,先用命令确认三件事:OSPF邻居状态正常、路由表里外部路由都有、R2和R3能ping通R4背后的网段。这个基线如果不通过,后面一切免谈。

3. 路由策略配置核心实操:过滤、改属性和打标记

这一节是实验的重头戏。我按“过滤-改属性-打标记”的顺序来做,每加一个策略,都立刻看一次路由表变化。

3.1 用前缀列表做路由过滤:该挡的挡在外面

实验需求1是让R2不要学习到172.16.20.0/24这个外部网段。这里我选择在R2上做入方向过滤,也就是在R2接收R1通告的路由时,把这条路由丢掉。

为什么不在R1上做出方向过滤?两个方向都能实现,但效果有差别:在R1上对R2发布方向过滤,会影响所有从R1发往R2的路由,适合“这个邻居就是不该知道这些路由”的场景;在R2上做入方向过滤,只影响R2自己,适合“R2自己有特殊要求”的场景。实验里如果只有R2不需要这条路由,强烈建议在R2入方向做,因为这样R1不需要为不同邻居维护不同策略,出方向策略一旦写死,后面新增分支时会很难扩展。

匹配工具我优先用前缀列表,而不是ACL。原因是ACL匹配路由时习惯用反掩码,很容易把掩码长度漏掉;前缀列表则直接表达“某个网络/某个掩码长度”,还支持ge、le动态匹配一段掩码范围,语义更清晰。

R2上的配置思路如下:

ip prefix-list BLOCK-EXT deny 172.16.20.0/24 ip prefix-list BLOCK-EXT permit 0.0.0.0/0 le 32

然后在OSPF视图下调用:

router ospf 1 distribute-list prefix BLOCK-EXT in

这里有个细节:前缀列表里如果只有deny语句,没有后面那条permit,会变成默认拒绝所有路由,R2会把OSPF学到的所有路由全丢掉。所以一条宽松的permit规则很重要,除非你真的要全部拒收。

配完之后,在R2上查看路由表,172.16.20.0/24应该消失,而其他外部路由仍然存在。如果你发现没有生效,先检查前缀列表里掩码写没写对,再检查方向是in还是out,最后确认distribute-list是不是被别的调用覆盖了。

3.2 用route-map改写路由度量:让路由器“觉得”某条路很远

实验需求2是让R3访问10.10.0.0/16时,认为通过R1过来的路径“开销大”,从而在有其他可选路径时自动优选别的链路。这里我用route-map把该路由的OSPF外部路由度量改大。

先定义一条route-map,匹配10.10.0.0/16,然后设置metric为200:

route-map SET-METRIC permit 10 match ip address prefix-list MATCH-1010 set metric 200

对应的前缀列表:

ip prefix-list MATCH-1010 permit 10.10.0.0/16

然后把这个route-map用于重分布或发布方向。因为10.10.0.0/16是从静态路由重分布进OSPF的,最合适的调用点是在重分布时:

router ospf 1 redistribute static route-map SET-METRIC

配完之后,在R3上查看路由表,10.10.0.0/16的OSPF路由应该有metric 200。如果网络里还存在另一条等价或更优路径,路由器会自动选择开销小的那一条。这就是“改属性影响选路”的本质逻辑——不是直接指定下一跳,而是通过调整协议计算依据,让路由器自己做出我们希望的选择。

实际生产里,这种做法常用于多出口选路、专线备份、以及跨区域流量调度。比起静态路由指向,它更灵活:一旦某条链路断开,OSPF会重新计算,流量自动切换,不需要人手工去改。

设置metric时有个注意事项:别把值调得过大,否则在某些协议里可能导致路由被当成不可达,反而出现丢路由的情况。OSPF外部路由的度量值是与链路开销累计的,建议在目标路由上先看原metric是多少,再逐步增加,别一步加到几千。

3.3 给路由打tag:跨协议传递“身份信息”

实验需求3是让从R4来的外部路由在重分布时带上标记,这样R3侧可以统一按标记做策略,不必逐条匹配网段。

路由标记(tag)本质上是一个数值标签,它可以随着路由一起传递。OSPF在外部LSA里专门有tag字段,RIP也有tag字段,BGP则通过community等属性实现类似功能。实验里,我在R1重分布静态路由时给所有外部路由打上tag 100:

route-map REDIST-TAG permit 10 match ip address prefix-list MATCH-ALL set tag 100

然后重分布调用:

router ospf 1 redistribute static route-map REDIST-TAG

R3上就可以这样处理:只对tag为100的路由做动作,比如降低优先级:

route-map ADJUST-TAG permit 10 match tag 100 set metric 200

在R3的OSPF入方向或接口下调用这条route-map,就能把R4侧重分布过来的这组路由统一调整成本地认为较高的开销。如果以后R4侧新增网段,只要在R1重分布时仍然打tag 100,R3的策略就自动覆盖新网段,不需要因为网段变了去改一堆策略。

这里要特别提醒:tag在重分布时有可能丢失。不同协议之间的tag承载规则不同,比如从BGP重分布到OSPF时,默认不会自动带community值;某些设备从静态路由重分布到OSPF时,如果不显式设置,tag默认是0。做跨协议实验时,每到一个节点就查看一次tag,确认它真的传过来了,再继续下一步。

3.4 匹配顺序与隐含拒绝:这是实验翻车率最高的地方

route-map和前缀列表都是“顺序匹配”的:从编号小的开始,逐个匹配,一旦命中就不再看后面的规则。如果整条route-map遍历完都没有匹配项,那么路由会被隐式拒绝。

这个坑非常隐蔽。比如你写了route-map只匹配了两个网段,其他路由因为没匹配到任何规则,全部被丢弃。很多人在重分布时发现路由突然“丢了一半”,就是忘了route-map默认的隐含deny行为。

解决办法是在策略末尾加一条“放行其他”的规则:

route-map REDIST-TAG permit 99

这条规则不匹配任何条件,含义就是“剩下所有路由都放行,不做属性修改”。加了它之后,你的明确匹配规则管特殊行为,兜底规则管常规路由,整个策略才完整。

再看一个多个规则的例子。如果我想把网段A设置metric 100,网段B设置metric 200,其余保持默认,那么route-map应该这样设计:

route-map MULTI permit 10 match ip address prefix-list PREFIX-A set metric 100 route-map MULTI permit 20 match ip address prefix-list PREFIX-B set metric 200 route-map MULTI permit 30

顺序非常重要。如果permit 30放在最前面,那所有路由都先被兜底规则放行,后面的10和20根本不会执行。这个和防火墙规则一样:精确匹配在前,宽松匹配在后。

4. 验证与故障排查:策略有没有生效,怎么定位问题

配置只是开始,真正的挑战在于验证和排障。下面这套方法是我反复用下来的,基本能覆盖这个实验里的大多数场景。

4.1 验证方法:怎么看策略真的生效了

策略配置完成后,不会像接口配置那样直观看到效果,得主动去查。

先看路由表。R2上过滤了172.16.20.0/24之后,在R2上执行路由表查询命令,应该看不到这条路由,但能看到172.16.10.0/24和10.10.0.0/16。如果这两个也消失了,说明过滤规则放错了位置或前缀列表隐含拒绝了一切。

再看路由属性。R3上查询10.10.0.0/16这条路由,能看到metric为200;查询其他外部路由,metric应该保持默认值。如果所有外部路由的metric都变了,说明route-map里的匹配条件不够精确,或者是兜底规则放到了前面。

还要验证路由的tag。在R3上用带tag字段的路由表显示命令查看,确认从R4重分布过来的路由确实带着100,而OSPF区域内部路由没有这个tag。

最后走一遍数据面验证:在R2和R3上分别traceroute到172.16.20.0/24和10.10.0.0/16两个目标。如果过滤生效,R2上第一跳就应该不通或者没有路由;如果metric改写生效,R3去10.10.0.0/16应该自动走上一条低开销路径。数据面的结果往往比路由表更能说明问题,因为路由表是“控制面”的结果,而用户感知的是“数据面”的结果。

4.2 我踩过的几个典型坑

这个实验我重新做了好几遍,每一遍都能踩到不同的坑,说几个最典型的。

第一个坑是ACL和前缀列表的掩码匹配问题。用ACL匹配路由时,反掩码写错会导致过滤完全失效。前缀列表相对好一些,但如果你用ge或le时把范围写反,比如le 32写成le 24,那结果就是完全不一样的匹配范围。我的习惯是:过滤具体明细路由时,前缀列表直接写完整掩码,不带ge/le,最不容易出错。

第二个坑是方向搞反。在R2上做入方向过滤时,我把distribute-list误写成了出方向,结果R2没收到过滤后的正确路由,反而把R2自己的路由分发受到影响了。排查了很久才发现方向写反了。建议配置时先想清楚:你要影响的“这个节点自己的路由表”,还是“别人看到的路由表”?

第三个坑是route-map配置了却没有被调用。route-map本身只是一个“策略模板”,必须被绑定到某个协议动作上才会生效,比如重分布时、路由学习时、发布路由时。如果你只创建了route-map,没有在OSPF或BGP视图下调用,它完全不会起作用。这属于低级错误,但也是最常见的错误之一。

第四个坑是隐含拒绝。看起来配了一条只改部分路由属性的route-map,结果其他路由全部消失。基本就是没有加最后那条permit兜底规则。这个问题在重分布操作里特别容易碰到,因为重分布本身是一个“主动放行”的动作,再叠加策略里的默认拒绝,双重作用下就容易把路由全丢了。

4.3 故障排查思路与速查表

排障时我习惯按顺序来,不跳步。先确认底层没有问题,再逐层加策略,这样能快速缩小范围。

排查顺序:

  1. 确认OSPF邻居是否正常。邻居如果Down了,路由表缺失就轮不到策略背锅。
  2. 看路由表,确认“有没有”和“对不对”。先问:这条路由是否存在?再问:属性对不对?
  3. 检查过滤和route-map有没有被正确调用到协议进程下。
  4. 查看路由的tag和来源,确认跨协议传递时没有丢属性。
  5. 查看策略匹配计数,很多设备支持查看route-map命中次数。如果计数为0,说明匹配条件有问题,或者流量走的是其他路径。

下面这张表是我自己做的速查表,基本覆盖了常见问题:

故障现象可能原因检查方法处理方法
过滤后路由全消失前缀列表或route-map隐含拒绝查看列表规则,确认是否有permit兜底增加兜底permit规则
过滤不生效掩码或反掩码写错查看列表匹配项,用测试命令匹配修正前缀或ACL掩码
路由属性没被改写route-map没调用检查协议视图下是否有调用语句在相应位置apply route-map
所有路由都被改写了匹配条件太宽松检查前缀列表是否包含0.0.0.0/0收紧匹配范围
tag丢失跨协议重分布时未保留查看每个节点的路由tag在重分布route-map中显式set tag
策略匹配计数为0路由走了另一条路径或匹配顺序不对查看路由来源、调整匹配序号检查前缀列表顺序和protocol来源
配置了策略后邻居断开过滤到了协议报文查看邻居状态和过滤列表确保过滤不限制组播或协议报文

做实验时,养成每改一步就看一次路由表和匹配计数的习惯,排查速度会快很多。不要一口气堆五六个策略再去看结果,那样出了问题基本只能全删了重来。

我个人做这个实验最大的体会是:路由策略像是一套“规则说明书”,你在哪个节点、哪个方向、哪个协议阶段写规则,决定了它最终影响的范围。一开始别急着写命令,先把“要过滤什么、要改写什么、在谁上面做”这三件事理清楚。命令反而简单,思路最难。这个实验做完之后,再去碰复杂的多协议重分布、BGP选路、策略路由,思路都是通的,只是工具多了一些而已。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进