RIP与OSPF双向重发布实战解析:从路由环路到种子度量排错

发布时间:2026/10/20 12:05:03
RIP与OSPF双向重发布实战解析:从路由环路到种子度量排错
作为一名常年跟多协议网络打交道的工程师我对重发布这三个字其实是有点敬畏的。早几年做实验时我在一台路由器上敲下 redistribute 命令以为从此 RIP 和 OSPF 就能互通有无结果路由表里瞬间出现一堆奇怪的路由数据包绕了大半个网络又回到了起点差点把一台核心设备搞到 CPU 满载。那次事故让我明白重发布实验不是把 A 协议抄进 B 协议这么简单它背后牵扯到种子度量、路由回灌、环路抑制、管理距离等一系列连锁反应。这篇博客就把我当时做过的重发布实验完整复盘一遍。我会先讲清楚重发布到底要解决什么问题再给出可复现的拓扑配置然后重点拆解双向重发布时最容易踩的环路坑和种子度量坑最后用验证手段说明数据平面到底走了哪条路径。无论你是刚学动态路由的网工新人还是在准备认证的实验党这篇内容应该都能让你少走几个弯路。1. 重发布到底在解决什么问题1.1 两个独立协议域的数据孤岛很多企业网络并不会只用一种动态路由协议。合并进来的子公司可能还在跑 RIP新建设的骨干网清一色 OSPF甚至某些边缘设备为了对接运营商还会接上 BGP。协议不同天然语言不通OSPF 用链路状态计算最短路径树RIP 靠跳数逐跳传递整张路由表。两个协议域内部都能自洽但到了边界路由上两边的路由表就像隔了一堵墙彼此根本不知道对方那边有什么网段。没有重发布的时候边界路由器上只能靠手写静态路由把关键网段指过去。小规模没事一旦路由条目超过几十条静态路由就会变成维护噩梦。某个新网段上线你得同时改好几台设备某条链路断了静态路由不会自己收敛。所以实验的第一目的就是模拟这种真实场景左边是 RIP 域右边是 OSPF 域中间用一台边界路由器连接通过重发布让两边自动交换路由信息。1.2 重发布的本质在两套路由表之间建立桥梁从实现原理看重发布就是把路由表里来自协议 A 的路由条目以协议 B 的路由格式重新注入到协议 B 的路由进程里。边界路由器在这个过程中充当翻译官。每个协议对路由优劣的判定标准不一样OSPF 看 costRIP 看 hop count所以翻译的时候必须给路由加上一个初始开销这个初始值就是种子度量seed metric。如果种子度量设置不当比如把 OSPF 路由重发布进 RIP 时不指定度量RIP 默认会认为这条路由的跳数是无穷大直接拒绝放进路由表。实验中很大一部分时间其实不是花在敲命令上而是花在理解这种翻译规则上。理解了这一点后续配置才有依据。2. 拓扑搭建和基础配置先把几个协议老老实实跑起来2.1 实验拓扑与地址规划我用三台路由器做了最简拓扑R1 跑 RIPR2 同时跑 RIP 和 OSPFR3 跑 OSPF。R2 就是边界路由器承担重发布任务。地址规划如下环回口模拟业务网段设备接口网段协议R1Loopback010.0.1.1/24RIP模拟 R1 侧局域网R1G0/0192.168.12.1/24连接 R2R2G0/0192.168.12.2/24连接 R1R2G0/1192.168.23.2/24连接 R3R2Loopback02.2.2.2/32管理地址R3G0/0192.168.23.3/24连接 R2R3Loopback010.0.3.3/24OSPF模拟 R3 侧局域网所有设备用模拟器起就行物理设备也可以关键是两台边界设备之间不要跑任何额外策略先把干净环境跑通再逐步加重发布规则这样排错时变量最少。2.2 基础配置命令与验证R1 的 RIP 配置很简单宣告直连网段即可R1(config)# router rip R1(config-router)# version 2 R1(config-router)# no auto-summary R1(config-router)# network 10.0.0.0 R1(config-router)# network 192.168.12.0R3 的 OSPF 配置R3(config)# router ospf 1 R3(config-router)# router-id 3.3.3.3 R3(config-router)# network 192.168.23.0 0.0.0.255 area 0 R3(config-router)# network 10.0.3.0 0.0.0.255 area 0R2 先同时配置两种协议但不做重发布R2(config)# router rip R2(config-router)# version 2 R2(config-router)# no auto-summary R2(config-router)# network 192.168.12.0 R2(config)# router ospf 1 R2(config-router)# router-id 2.2.2.2 R2(config-router)# network 192.168.23.0 0.0.0.255 area 0 R2(config-router)# network 2.2.2.2 0.0.0.0 area 0此时验证一下在 R1 上应该只能看到 10.0.1.0 和 192.168.12.0 这两条 RIP 路由根本看不到 10.0.3.0 和 192.168.23.0。在 R3 上则看不到 RIP 域的路由。这正是两个协议域互不相通的初始状态也是重发布要做出的改变。3. 双向重发布的第一个教训路由回灌导致的环路3.1 双向重发布到底该怎么配置要让两边互通最简单的做法是在 R2 上做双向重发布把 OSPF 学到的东西喂给 RIP也把 RIP 学到的东西喂给 OSPF。命令如下R2(config)# router rip R2(config-router)# redistribute ospf 1 metric 3 R2(config)# router ospf 1 R2(config-router)# redistribute rip subnets metric 20第一行表示 OSPF 路由注入到 RIP 时初始跳数设为 3第二行表示 RIP 路由注入 OSPF 时cost 设为 20。我当时天真地以为这样配置完就万事大吉结果一查看 R2 路由表差点笑不出来。3.2 为什么回灌会带来路由环路距离矢量协议都这样双向重发布跑起来后R2 会把从 OSPF 学到的 10.0.3.0/24 重发布进 RIPR1 能收到这条路由。同时R1 原本就有一条直连路由 10.0.1.0/24它通过 RIP 通告给 R2R2 再把 10.0.1.0/24 重发布进 OSPFR3 也能收到。表面上一切正常但问题出在 R1 身上。R1 可能通过 RIP 听到一条从 OSPF 重发布进 RIP的路由这条路由的目的地其实是某个 OSPF 网段而 R1 本身对这个网段一无所知只能把数据交给下一跳 R2。这是正常行为。但如果 OSPF 域里也出现了 RIP 域内部的某个网段而 RIP 域内部该网段的真实来源设备收到这条回灌路由它可能认为还有一个远端路径可以到达这个网段于是把原本应该直接转发的流量绕到边界路由器上。更典型的环出现在单向重发布漏配过滤时R3 通过 OSPF 学到 10.0.1.0/24这条路由来自 RIP 域重发布如果 OSPF 域内部又把 10.0.3.0/24 通过重发布回灌到 RIP 域RIP 域内的 R1 就会看到一条去往 10.0.3.0/24 的路径而这条路径的下一跳还是 R2R2 又回过头在 OSPF 域内找 10.0.3.0/24 的源头。数据包在 R1 和 R2 之间来回送TTL 不断递减直到丢包。RIP 这种距离矢量协议更新路由时只关心跳数不会做拓扑图的全局判断所以非常容易把这种回灌路由当成一条有效路径。OSPF 属于链路状态协议本身自带防环机制但重发布进来的外部路由是外部注入的OSPF 无法自动判断它是否应该存在。于是无论哪种协议做双向重发布回灌都是头号隐患。3.3 控制回灌的两种常用手段我试过两种有效手段都推荐写进实验笔记。第一种是在重发布时用 distribute-list 过滤回灌路由。以 R2 为例我不想让 RIP 域内的直连网段 10.0.1.0/24 跑进 OSPF 后再被 OSPF 学回来也不想让 OSPF 域内的网段被 RIP 学回来后又被重发布回 OSPF。可以配置前缀列表把需要保护的路由挡在重发布的入口外R2(config)# ip prefix-list BLOCK_LOOP seq 5 deny 10.0.1.0/24 R2(config)# ip prefix-list BLOCK_LOOP seq 10 permit 0.0.0.0/0 le 32 R2(config)# router ospf 1 R2(config-router)# distribute-list prefix BLOCK_LOOP in但 distribute-list in 只能过滤进入 OSPF 进程的路由对于 R2 内部的回灌判断还不够精确。更好用的是路由打标记route tagging方案重发布进 OSPF 的 RIP 路由打上 tag 100重发布进 RIP 的 OSPF 路由打上 tag 200然后再写 route-map 拒绝掉 tag 匹配的外部路由。这种方式生产环境里维护起来最清晰也方便排错。当时我用了更直接的办法单向重发布只在 R2 上把 RIP 重发布进 OSPF同时在边界方向用静态路由指回 RIP 域。这种方案可以避免双向回灌但要维护的静态路由也不少实验时评估一下工作量根据实际情况选择。4. 种子度量是个坑为什么重发布后的路由老是不通4.1 种子度量的默认值和惨案现场我第一次做重发布时第一版配置里漏掉了 metric 和 subnets 关键字结果 R3 上死活学不到 RIP 域的路由。查了半天发现 OSPF 对重发布进协议的路由如果没有特殊处理默认不接收外部路由必须加上 subnets 参数才会通告子网路由。RIP 更讲究。把 OSPF 路由重发布进 RIP如果不显式指定 metricRIP 默认把这条路由的跳数设为 16而 16 在 RIP 语义里就是不可达。R1 收到这条路由之后只会把它当垃圾丢弃控制层面看路由表根本没有 10.0.3.0/24。所以我当时补上metric 3R1 的路由表才出现跳数为 3 的外部路由。如果重发布进 OSPF 不指定 metricOSPF 默认会给外部路由一个 cost 20OE2 类型。20 意味着什么如果 OSPF 域内部有路径到达同一网段且内部 cost 小于 20OSPF 会优先选择内部路径只有内部路径不存在或者内部 cost 大于 20外部路由才会被选中。很多时候这会导致流量明明应该走重发布的出口结果却绕道很远问题不太好排查。4.2 用 route-map 精确控制重发布行为单纯的redistribute rip metric 20只能对所有 RIP 路由统一设置一个种子度量没办法针对不同网段区别对待。我后来养成了用 route-map 包裹重发布的习惯一套配置既能控制度量又能顺手做过滤和打 tag。示例配置R2(config)# route-map REDIS_TO_OSPF permit 10 R2(config-route-map)# match ip address prefix-list RIP_LOOP R2(config-route-map)# set metric 50 R2(config-route-map)# set tag 100 R2(config)# router ospf 1 R2(config-router)# redistribute rip route-map REDIS_TO_OSPF subnets上面这段命令的意思是只有匹配 RIP_LOOP 前缀列表的 RIP 路由才允许进入 OSPF并且 cost 强制改成 50打上 tag 100。实验中 R3 收到 10.0.1.0/24 时看到的外部度量就是 50可以完整验证重发布策略是否生效。我在实测中发现把外部路由类型从 OE2 改成 OE1使用metric-type 1关键字在很多场景下更符合直觉。OE2 只看外部种子度量OSPF 内部路径的 cost 不累加OE1 则会累加从边界路由器到目标的开销路径选择更接近真实链路质量。实验时如果发现流量总是不走预期出口我会先检查是不是 OE2 的默认特性导致选路偏差。5. 实验现象验证与数据平面排查5.1 控制平面验证命令组合配置只完成一半剩下的一半是验证。先看 R2 上重发布的结果R2# show ip route关注外部路由标志RIP 重发布进 OSPF 后路由表里会出现O E2前缀的路由那就是外部学习到的条目。在 R1 上则能看到 RIP 路由出现 OSPF 域网段的条目。此时再检查各设备的路由表是否完整。用show ip protocols可以自查各协议的 filter 和 redistribute 列表是否生效如果配置了 route-map这里会显示具体关联关系。生产环境里这是首选排查命令比反复敲 show run 快得多。5.2 数据平面抓包分析控制平面通不代表数据平面顺畅。我实验时模拟了 R1 要 ping 通 R3 的 10.0.3.3 的场景。在 R2 与 R1 相连的接口上做抓包观察 ICMP 报文是否还在反复被转发到其他接口。一旦出现 TTL exceeded基本就是环路已经发生了。检查数据平面时还要注意源目地址的往返路径是否一致。重发布后的网络中去程走 RIP→OSPF回程可能走 OSPF→RIP如果其中一段被过滤或者路由表缺失就会出现单向丢包。我在实验里遇到过去程能通、回程却不通的情况最后发现是 OSPF 域内某台设备上有一条静态路由指向了错误下一跳重发布本身没有任何问题。这个教训说明出现故障时不要第一时间怀疑重发布先把两端路由表对比一下再做抓包判断。5.3 真实模拟中的断连排障演示为了演示完整排障思路我特意把 R2 上的 route-map 临时改成拒绝 RIP 环回路由R2(config)# ip prefix-list DENY_RIP_LOOP seq 5 deny 10.0.1.0/24 R2(config)# ip prefix-list DENY_RIP_LOOP seq 10 permit 0.0.0.0/0 le 32 R2(config)# route-map REDIS_TO_OSPF permit 10 R2(config-route-map)# match ip address prefix-list DENY_RIP_LOOP R2(config-route-map)# set metric 50这个时候从 R3 ping 10.0.1.1 应该失败因为 10.0.1.0/24 根本没有进入 OSPF。我在 R2 上show ip route ospf确认外部路由消失再查 R3 路由表也确实没有 10.0.1.0/24。这种一步步缩小范围的方法比一上来就折腾链路要好用得多。实验里培养这种结构化的排查习惯到了生产环境能省下大量故障时间。6. 生产环境里我反复强调的几条红线6.1 过滤一切你不想暴露的路由很多人在实验里追求全网互通把边界路由器的所有直连和环回全都不加选择地重发布出去。生产环境千万别这么干。管理地址、内部保留网段、终端接入网段这些暴露出去只会增加路由攻击面。我的经验是明确列出允许重发布的网段清单用前缀列表做白名单不在白名单里的统统拒绝。这样即使边界设备之后新增了网段也不会因为忘了配置而把敏感路由传播出去。6.2 管理距离的非常规调整重发布之外还有一个分支问题值得单独说当同一台路由器从两种不同协议学到同一个网段并且都出现在路由表时路由优先级由管理距离决定。OSPF 内部路由管理距离是 110RIP 是 120。默认情况下 OSPF 的路由会胜出。我遇到过一种情况两个协议域之间确实有几个网段完全重叠而我希望 RIP 域的路由优先因为它在物理链路上时延更低这时候单纯调整种子度量没用必须调整管理距离才能实现预期。实验时千万不要养成乱调管理距离的习惯尤其不要为了应付考试把所有协议距离全部改成一样。管理距离一旦搞错可能让整张路由表的行为变得诡异而且这种问题非常难排查。6.3 从实验走向现实的补充建议最后给想把这个实验往生产环境迁移的读者几点建议。第一重发布配置一定要做好回滚预案建议在边界设备上提前保存重发布前的配置文件。第二上线前先在隔离环境里仿真一遍模拟真实的流量负载看边界路由器的 CPU 是否扛得住。第三监控上要配置路由抖动告警重发布出的路由一旦出现频繁撤销和重新注入往往比链路故障更先暴露问题。我在实际项目里见过不少因为重发布细节没处理好而引发的生产事故其中最常见的就是双向重发布时漏配过滤。这篇实验里的每个坑基本都是从那种真实事故里反过来推出来的。希望你能把实验做透把坑提前踩一遍而不是在生产网络里重温这些教训。