这是OSPF系列实验报告里的第三篇,主题就是那个经典的OSPF综合实验。前两个实验分别做了单区域邻居建立和基础LSA查看,这次把多区域互联、路由重分布、末梢区域、接口认证全部塞进一张拓扑里。很多人在学OSPF时是分点学的——邻居怎么建立、区域怎么划分、报文有哪几种——但一到综合实验就卡壳,因为所有知识点同时出现,优先级和依赖关系一下子理不清。这篇报告的价值在于:我把整个实验从拓扑设计、地址规划、基础配置,到报文交互验证、故障排查、进阶收尾配置完整走了一遍,所有命令和判断思路都基于实际操作。
这篇东西适合谁看?两类人。一是准备网络实验或考试的人,需要一份能直接对照的OSPF综合实验全流程;二是工作中要碰动态路由的运维和网工,平时只配过静态路由,想看看OSPF配置和排错到底怎么玩。看完你至少能:独立搭一个多区域OSPF拓扑,手写每个环节的配置命令,并且当邻居起不来时知道第一步查什么、第二步看什么。下面我按实验推进顺序写。
1. 一张拓扑图背后的实验需求:单区域、多区域和重分布都要覆盖
1.1 综合实验到底在考察什么
综合实验和单项实验最大的区别在于:它不告诉你“这一步该配OSPF”了,而是给你一组连通性需求,让你自己判断哪些接口要宣告进OSPF、哪些区域要划分、路由要怎么汇总。同一个“全网互通”的实验目标,有人半小时搞定,有人折腾一个下午还看到一堆路由缺失,差别往往不在手速,而在实验开始前的需求拆解。
考察点通常落在这几个方面:
- 邻居建立:多台设备之间能否正常形成Full邻居,这是所有上层功能的前提
- 区域规划:骨干区域Area 0和非骨干区域的连接关系是否合法,ABR角色落在哪台设备上
- 路由学习:非骨干区域的路由能否通过ABR正确传递到骨干区域,Type 3 LSA的传播方向是不是对的
- 路由控制:能不能通过汇总、区域类型、cost调优来压缩路由表规模和改变选路
- 安全与稳定性:接口认证或区域认证是否配置到位,邻居关系会不会被非法设备干扰
如果只是照着命令敲,这些点全都会“看似通”。但一旦邻居建立失败或者路由学习不全,就不知道从哪下手——这正是综合实验的真正目的:逼着你把配置背后的逻辑串起来。
1.2 我用的拓扑与地址规划
综合考虑后,我用了四台路由器,拓扑是一个典型的“骨干+分支”结构:
- R1和R2位于Area 0,R2和R3位于Area 1
- R2身兼ABR,连接骨干区域和非骨干区域
- R4挂在R3下面,用来模拟一个末梢网络
- R1的Loopback 0模拟本地业务网段,R4的Loopback 0模拟远端业务网段
地址规划我全部手工指定,避免DHCP和动态地址干扰路由调试:
| 设备 | 接口 | IP地址 | 所属OSPF区域 |
|---|---|---|---|
| R1 | G0/0/0 | 10.0.12.1/24 | Area 0 |
| R1 | Loopback 0 | 1.1.1.1/32 | Area 0 |
| R2 | G0/0/0 | 10.0.12.2/24 | Area 0 |
| R2 | G0/0/1 | 10.0.23.2/24 | Area 1 |
| R3 | G0/0/0 | 10.0.23.3/24 | Area 1 |
| R3 | G0/0/1 | 10.0.34.3/24 | Area 1 |
| R4 | G0/0/0 | 10.0.34.4/24 | Area 1 |
| R4 | Loopback 0 | 4.4.4.4/32 | Area 1 |
Loopback地址同时承担Router-ID的选择功能,后面我会详细说为什么这样规划。这个拓扑看着简单,但单区域、跨区域、末梢分支、业务网段这几个要素都齐了,后续做汇总和认证也有足够的操作空间。
地址规划清楚之后,最关键的环节就是配置。很多人就是倒在这一步——命令没敲错,但邻居就是不起来。下一章我把配置阶段最容易翻车的三个点逐一展开。
2. network反掩码、进程号和区域号:配置阶段最容易翻车的三个点
2.1 进程号是本地参数,不是全局协议标识
不少刚接触OSPF的人会把“进程号”当成一个需要全网统一的东西。实际不是。OSPF进程号只在本地设备有意义,同一台设备上可以起多个OSPF进程,但不同设备之间即使进程号不一样,也能正常建立邻居关系。
我这次实验在R1上用的process 1,R2、R3、R4上同样用process 1,但这不是必须的。真要说有什么影响,进程号主要影响本地的路由表管理和协议优先级,跟邻居报文交互完全无关。如果你在两台设备上看到邻居状态到不了Full,先别怀疑进程号不一致——真正要检查的是区域号、接口地址、掩码和认证这些东西。
2.2 network命令:反掩码和区域号必须同时匹配
华为设备上的OSPF宣告命令格式是:
ospf 1 area 0 network 10.0.12.0 0.0.0.255这里的0.0.0.255是反掩码,不是子网掩码。反掩码的计算方式是用255.255.255.255减去子网掩码。比如24位掩码255.255.255.0,反掩码就是0.0.0.255;如果是30位掩码255.255.255.252,反掩码就是0.0.0.3。
反掩码里0表示“必须匹配的位”,1表示“可以任意变化的位”。所以network 10.0.12.0 0.0.0.255的意思是:只要接口IP的前24位是10.0.12,就匹配这条宣告。换句话说,同一个网段里的任何接口都会被宣告进指定的区域。
最容易翻车的点有三个:
- 反掩码写成了子网掩码。有人会把掩码255.255.255.0直接填进去,导致宣告范围变小,接口没有匹配上,邻居自然起不来
- network网段写错。接口是10.0.12.1/24,宣告时写network 10.0.12.1 0.0.0.255,这种其实也能匹配,但如果统一写成network 10.0.12.0 0.0.0.255更规范,不容易引起混淆
- 宣告的区域号和邻居的区域号不一致。两边都宣告了相同网段,但一个在area 0一个在area 1,邻居永远停在Init状态,error表里会给出Area mismatch的计数
2.3 Router-ID:默认选择和手工指定的坑
Router-ID是OSPF设备在自治系统内的唯一标识,报文中到处都带着它。设备的Router-ID选择规则通常是:
- 手工配置的router-id优先
- 如果没有手工配置,取Loopback接口中IP地址最大的那个
- 如果也没有Loopback,取物理接口中IP地址最大的那个
这正是我上面把Loopback规划为1.1.1.1和4.4.4.4的原因——既有业务模拟的价值,也能让Router-ID稳定。但这里有个隐藏坑:如果Loopback接口没有宣告进OSPF,Router-ID依然会被选出来,只是这个Loopback路由不会出现在OSPF路由表里。很多人的实验里邻居建立不成功,查了半天发现是两台设备的Router-ID冲突。尤其是用模拟器批量复制设备时,默认Router-ID经常重复。解决办法很直接:在OSPF进程下手工配置router-id 1.1.1.1,配置完记得reset ospf process重启进程,否则旧Router-ID继续生效。
配置阶段到这里,理论上邻居应该能建起来了。但“理论上”三个字恰恰是实验里最靠不住的东西。下一章从报文角度讲一讲Full这个状态是怎么一步步达成的,这也是排查的基础。
3. 从Hello到Full:OSPF五种报文在实验中的实际交互顺序
3.1 五种报文各自的职责
OSPF的报文类型一共五种,每一种在一个实验里都能遇到。理解它们分别解决什么问题,排错时会少走很多弯路。
| 报文类型 | 编号 | 作用 |
|---|---|---|
| Hello | 1 | 发现和维护邻居关系,协商Hello/Dead时间、区域、认证等参数 |
| DBD | 2 | 数据库描述报文,主从协商后向邻居简述本地LSDB的摘要信息 |
| LSR | 3 | 链路状态请求,发现自己LSDB中缺少或过期的LSA后向邻居请求 |
| LSU | 4 | 链路状态更新,真正携带完整的LSA内容进行同步 |
| LSACK | 5 | 链路状态确认,收到LSU后确认收到,保证可靠传递 |
如果把邻居建立过程类比成两个人对账:Hello是打招呼确认“咱俩都在”,DBD是双方交换账本目录,LSR是“你目录里这条我没见过,发我看看”,LSU是把完整明细发过去,LSACK是“收到,这条没问题”。
3.2 状态机走到哪一步,问题通常就出在哪一步
邻居状态从Down到Full一共七个状态:Down、Init、2-Way、ExStart、Exchange、Loading、Full。对应到实验里,每个状态卡住都有一套固定的查法。
卡在Init:只收到了对方的Hello,但对方的报文中看不到本端设备。绝大多数是本端宣告的网段或区域和对方不匹配,也有可能是Hello/Dead时间不一致。
卡在2-Way:设备互相看到了,但不再往下走。在广播型网络中这是正常状态,因为DR/BDR选举还没完成。如果一台设备上看到邻居长时间停在2-Way,多半是DR/BDR选举过程卡住了,或者网络类型被手动改过。
卡在ExStart:DBD报文交互失败。最常见的元凶是接口MTU不一致。这是一个非常典型的实验故障,我专门留了一节在后面完整走一遍排查过程。
卡在Exchange:DBD摘要交换不完整,区域ID、认证不匹配也会在Exchange阶段反复震荡。
卡在Loading:LSR发出去之后LSU迟迟不来,或者LSACK丢失,导致数据库始终没有同步完成。这种问题相对少见,常见诱因是链路拥塞或接口下配置了奇怪的过滤策略。
3.3 接口协商参数:Hello/Dead时间与网络类型
Hello报文里携带了Hello间隔和Dead间隔。广播网络默认是10秒和40秒,NBMA网络默认是30秒和120秒。两边接口如果Hello/Dead不一致,直接卡在Init,表现为一直能收到报文但始终无法进入2-Way。判断方法用display ospf interface看接口下的Timer值,两端的值一对比就出来了。
网络类型不一致也是经典坑。一边是广播网络,一边被手动改成point-to-point,两边接口参数对不上,Hello也进不来。我建议在实验里,互联接口如果本来就是点到点链路,就用默认的广播类型即可,不要手动画蛇添足。真要改成p2p,一定两边一起改,别只改一端。
报文层面理解到这儿,至少你已经知道从哪个状态去定位问题。但光知道状态机还不够,真出问题时手里得有趁手的查询工具。下一章重点写error计数器和debug命令的实际用法,这也是这次实验里最花时间琢磨的部分。
4. 不抓包也能排错:error计数器和debug命令的实战用法
4.1 看error表:最清晰的定位入口
在实验环境里,很多人遇到邻居起不来,第一反应是打开抓包软件。但在绝大多数场景下,根本不需要抓包。OSPF自己就在接口上维护了一个错误计数表,各种“对端拒绝”“参数不匹配”“认证失败”都会在这个表里留下记录。
查看命令是display ospf error interface GigabitEthernet 0/0/0。输出的每个字段都对应一种错误类型,比如:
- Hello timer mismatch:Hello/Dead时间不一致
- Area mismatch:区域号不匹配
- Duplicate router ID:Router-ID冲突
- Neighbor address mismatch:邻居地址匹配异常
- Authentication failure:认证失败
按照我这次的实验经验,90%的邻居建立失败,看这张error表就能直接得出结论。这个表的好处是它不像抓包那样需要你去分析协议栈,也不像debug那样刷屏,它给你的是一个“结果”:什么错了,就在哪里。
4.2 debug命令:定位交互过程细节
当error表显示一切正常但邻居就是起不来时,才需要去看真正的交互过程。OSPF相关的debug命令中最常用的两个是:
debug ospf packet debug ospf adjdebug ospf packet打印收发报文的细节,能看到Hello的序号、Router-ID、checksum等信息;debug ospf adj打印邻居状态机迁移的每一步,卡在哪个状态一目了然。
这里要特别提醒一句:开debug之前先确认terminal monitor开了,否则debug输出不会出现在终端上。看到debug输出刷屏后,定位到问题就立刻undo debug all,不要让调试输出持续消耗设备性能。实验中很多人一开debug忘了关,结果真正排错时被海量输出淹没,反而什么都看不出来。
4.3 不抓包的判断逻辑
不抓包不等于不看协议,而是把协议的判断都放到设备自身的查询结果里来。我在实验里习惯按顺序走三条命令:
- display ospf peer或者display ospf neighbor brief:先看邻居状态停留在哪个阶段
- display ospf error interface对应接口:看有没有错误计数
- display ospf interface对应接口:看接口是否宣告成功、网络类型、计时器参数
这三条命令走完,80%的问题已经能定位。只有遇到error表里没有计数、debug也看不出所以然的情况,我才会上抓包去看真实的报文交互。比如验证DR/BDR选举结果、确认LSA头的checksum是否一致这类“静态信息查不出来”的场景。
这一章说的排错手段,下一章用一次真实故障完整展开。我这次实验里,R2和R3的邻居一直卡在ExStart,就是那种配置看起来都对、error表也没明显报错、但状态就是不动的情况,排查过程比较典型。
5. 邻居卡在ExStart的完整排查链路:一次真实故障还原
5.1 现象与初步判断
实验配置完成后,在R2上执行display ospf peer brief,看到的结果是:
Neighbor ID Pri State Dead Time Address Interface 3.3.3.3 1 ExStart/BackupDr 34 10.0.23.3 GigabitEthernet0/0/1邻居ID是3.3.3.3,状态却始终在ExStart。这个状态的含义是:双方在协商后续DBD报文交换的主从关系,还没有正式开始传递数据库摘要。如果一直停在这里,说明DBD阶段的参数协商不成立。
第一轮排查我按顺序做了三件事:
- display ospf error interface GigabitEthernet 0/0/1:error表是空的,没有Hello timer mismatch或Area mismatch
- display ospf interface GigabitEthernet 0/0/1:网络类型是Broadcast,Hello 10s Dead 40s,和R3侧配置一致
- display ospf peer brief:确认3.3.3.3这个Router-ID确实是R3的
到这里,配置肉眼可见的部分全部一致,但邻居就是卡死。这就把嫌疑范围缩到了DBD报文交互本身。
5.2 怀疑MTU:用ping验证
DBD报文交互阶段的第一个协商项就是接口MTU。OSPF在DBD报文中会携带接口MTU值,当对端发现本端MTU大于自己的接口MTU时,会直接拒绝交换数据——这是保护机制,避免后续数据库同步产生分片问题。
这里有个容易忽略的细节:华为VRP默认情况下不检查DBD报文里的MTU,需要在接口下配置ospf mtu-enable之后才会启用这个协商流程。这次实验里R2和R3互联接口都开了OSPF MTU检查,所以MTU不一致立刻暴露出来,状态就锁死在ExStart。如果是思科设备,MTU检查默认开启,卡ExStart的故障会更加常见。
R2和R3互联接口默认MTU都是1500,按理说应该一致。但实验里R3的G0/0/1被人为调成了1400。这种配置差异在接口配置里非常隐蔽,因为MTU不在常规排查项里。验证方法用ping命令,指定报文大小为1401字节并设置不分片标志(华为VRP中为-s 1401 -f,思科中为size 1401 df-bit,不同版本参数略有差异):
ping -s 1401 -f 10.0.23.3如果返回消息表示需要分片而DF标志阻止了,就说明路径MTU小于1401,两边接口MTU不一致。这个验证比直接show interface更直观,因为即使接口配置显示相同,交换机链路或对端策略也可能改变实际可用MTU。
5.3 修复与验证
确认MTU不一致后,把R3的G0/0/1接口MTU改回1500:
interface GigabitEthernet 0/0/1 mtu 1500改完之后不用重启OSPF进程,MTU变化会触发接口状态变化,OSPF会重新进行邻居协商。大概几秒后,我在R2上再看邻居状态:
Neighbor ID Pri State Dead Time Address Interface 3.3.3.3 1 Full/BackupDr 36 10.0.23.3 GigabitEthernet0/0/1状态从ExStart直接变成Full。到这里故障解决,路由表也随之完整了。整个过程没有抓包,靠的是error表排除配置错误、ping确认MTU差异、debug辅助观察状态迁移。
这里也补充一个经验:如果你在现场看到DBD协商反复重置,除了MTU,还要检查双方的Router-ID。Router-ID冲突同样会导致ExStart阶段反复。区别在于Router-ID冲突时error表通常会出现Duplicate router ID计数,而MTU问题error表是空的。这个差异本身就是定位线索。
6. 收官配置:区域间汇总、末梢区域与认证的搭配思路
6.1 区域间路由汇总:把明细路由收口到ABR
实验拓扑跑通Full邻居后,路由表里会出现大量明细路由。R1的Loopback 1.1.1.1/32、R4的Loopback 4.4.4.4/32,加上各互联网段,路由条目虽不算多,但已经能看出明细化的趋势。生产环境中几十个网段全量下发,核心路由表的压力会很大,所以区域间汇总几乎是综合实验必做的内容。
在R2这台ABR上做汇总,把Area 1的路由收口后再通告给Area 0:
ospf 1 area 1 abr-summary 10.0.0.0 255.255.0.0这条命令的含义是:R2将Area 1内的10.0.23.0/24、10.0.34.0/24、4.4.4.4/32等内容汇总为10.0.0.0/16后,通告给Area 0。R1上就不会再收到明细路由,而是收到一条聚合路由。之后如果Area 1内新增一个10.0.5.0/24的网段,只要落在汇总范围内,Area 0端无需任何变化就能学到新路由,这就是汇总的实际价值。
注意华为的abr-summary命令是在区域视图下配置的,思科则是area 1 range 10.0.0.0 255.255.0.0。两条命令的语义一致,都是为了在ABR上对区域间路由做聚合。
6.2 末梢区域与完全末梢区域的取舍
非骨干区域有很多实现上的变体,综合实验里通常会让其中一个区域配置成末梢区域。末梢区域的本质是减少外部路由的传播:区域内部不再接收Type 5外部LSA,区域边界路由器会自动下发一条默认路由。
华为里的配置很简单,以R3和R4所在的Area 1为例:
- R2(ABR): ospf 1,area 1,stub
- R3和R4: ospf 1,area 1,stub
这里必须强调:区域内的所有路由器都得配置stub命令,否则无法建立邻居。这是很多实验里改到一半区域全断的原因——只在ABR上敲了stub,忘记区域内的其他路由器也要敲。
我这次实验选择的是完全末梢区域配置,在R2上:
ospf 1 area 1 stub no-summaryno-summary的含义是:不仅不接收Type 5外部LSA,连区域间的Type 3 LSA也不接收,只保留一条ABR下发的默认路由。R3和R4仍配置stub即可。这个组合在思科里叫totally stub,华为的写法是stub no-summary。
配置完成后,在R3上查看路由表,能看到一条指向R2的默认路由,所有外部明细全被抑制,路由表非常干净。这里有一个很容易混淆的点:完全末梢区域里,区域内的设备之间不能有虚链路等额外连接方式,否则会破坏stub区域的封闭性。实验设计时我把R3-R4这条链路就规划在Area 1内部,正好匹配这个需求。
6.3 接口认证:防住非法设备与误宣告
综合实验最后通常还要加认证,目的是防止不合法的设备接入OSPF域,也防止有人把个人设备插到交换机上触发路由震荡。认证配置有两种思路:接口认证和区域认证。接口认证命令在华为设备上是:
interface GigabitEthernet 0/0/1 ospf authentication-mode md5 1 cipher test区域认证则是:
ospf 1 area 1 authentication-mode md5 1 cipher test区域认证相当于给区域内所有接口统一设置认证,接口下不用逐条敲,管理更省事。但要注意两种方式混用时,接口下的配置会覆盖区域配置,排查时别忽略这个优先级。
MD5认证现在已经不算强了,但实验里足够展示“认证一致性”这个核心概念:两边的认证模式、认证类型、密钥ID必须完全一致,否则邻居会卡在Init,error表里出现Authentication failure计数。我在实验室里经常做这个验证实验:只改一端密钥,另一端error表立刻增加计数,非常直观。生产环境如果要上更强认证,现代设备支持HMAC-SHA256等更安全的算法,思路完全一样,只是命令参数不同。
配置完汇总、末梢区域和认证之后,记得回到R1和R4上验证一下路由表。R1应该能看到一条指向R2的聚合路由,R3和R4应该只能看到区域内明细加上一条默认路由。到这里,OSPF综合实验的主体工作就全部结束了。
最后说点这次实验的体会。OSPF综合实验最锻炼人的地方不在于把命令敲对,而在于把命令之间的依赖关系想清楚。配置顺序上,我强烈建议先把网络类型、计时器、MTU这些接口参数全部确认一遍,再去做OSPF进程和区域配置,否则真的会在排错时反复推翻前面的判断。排查顺序上,永远先看error表,再看邻居状态,最后才动debug或抓包。这三条原则我这次实验里全程遵守,所有问题都是十几分钟内定位的。“不抓包也能排错”不是口号,关键是让每个查询命令带着目的去执行,而不是漫无目的地刷屏看输出。这次实验报告就写到这里,下一轮我打算把OSPF和BGP之间的路由引入做一组对比实验,到时候再把新的结论整理出来。