翻到去年做的OSPF综合实验记录,当时把OSPF多区域、特殊区域、MSTP、VRRP这几个东西全部揉进一张园区网拓扑里,前后折腾了好几天。现在回头看,这个实验最大的价值不在于敲会了多少命令,而在于把协议之间的联动关系真正理清了。这篇文章就按实验的完整流程来写,从拓扑规划、地址设计、OSPF部署、特殊区域配置,到MSTP和VRRP联动调优,最后是故障排查实录,适合正在备考H3C/华为认证、或者正在做网络方向课程设计和园区网改造的朋友参考。我不会只贴配置,还会把每一步的配置理由和验证结果写清楚,毕竟纸上得来终觉浅。
1. 实验规划与拓扑设计思路
1.1 为什么要把OSPF、MSTP、VRRP放在一张拓扑里
很多朋友做OSPF实验都是两台路由器一接,宣告几个网段,看到邻居状态变成Full就觉得完事了。但实际上作网络工程项目时,OSPF很少单独存在,它一定要和二层技术配合起来用。这次实验我搭了一个典型的中小型园区网:两台核心交换机跑OSPF骨干区域,下面挂汇聚交换机划分多个业务区域,接入层交换机负责终端接入,再用MSTP解决二层环路问题,用VRRP做网关冗余。
这三个技术放在一起,是因为它们解决的问题完全不同但又互相依赖。OSPF解决的是三层路由怎么走,终端访问服务器、跨VLAN互访、访问出口互联网,都得靠路由表来指引。MSTP解决的是二层环路问题,接入层交换机之间、接入和汇聚之间通常有冗余链路,不做生成树就会形成广播风暴。VRRP解决的是网关冗余问题,终端配置的网关地址如果是一个虚拟IP,那么核心交换机挂掉一台,另一台能无缝接管转发。
真正的难点在于这三者不是孤立的。MSTP阻塞了某条二层链路之后,OSPF看到的拓扑就会变化,路由的下一跳和Cost值都可能跟着变;VRRP主备切换后,终端的默认网关换了转发路径,OSPF必须能感知到这种变化并重新收敛。如果只是单独验证某一个协议,这些联动问题永远发现不了。所以我从一开始就把实验目标定成:全网VLAN间互访正常、任意单点链路或设备故障后业务恢复时间可接受、主备切换过程中不出现长时间丢包。这三个目标才是综合实验的意义所在。
另外,为什么选OSPF而不是静态路由或者RIP,也是因为OSPF的收敛速度、无环特性和可扩展性更适合这种多区域的场景。OSPF把整个网络划分成Area 0骨干区域和多个非骨干区域,ABR负责区域间的路由传递,这种层次化设计和园区网的层次化架构天然匹配。RIP的跳数限制和慢收敛在大型网络里完全不够用,静态路由在链路故障时又无法自动收敛。OSPF虽然配置复杂度高一些,但换来的稳定性和可控性值得投入。
1.2 地址规划与Router-ID设计
做实验也好,做项目也罢,地址规划永远是第一步,而且是最容易偷懒出问题的一步。这次实验我规划了三类地址:互联地址、Loopback地址和业务VLAN地址,分别用了不同的网段区分,具体如下表。
| 设备/区域 | 网段规划 | 用途说明 |
|---|---|---|
| 核心-核心互联 | 10.0.0.0/30 | 两台核心交换机之间的三层互联链路 |
| 核心-汇聚互联 | 10.0.x.0/30 | 核心与各汇聚之间的上行链路 |
| Router-ID地址 | 1.1.1.1到1.1.1.x | 各设备Loopback 0,用于OSPF Router-ID |
| 业务VLAN网段 | 192.168.10.0/24等 | 终端用户所在的业务子网,配置在VLAN接口上 |
这里要特别说一下Router-ID。OSPF的Router-ID是用来标识一台路由器的唯一身份,类似于人的身份证号。如果不手动配置,设备会从接口IP里自动选一个最大的IP作为Router-ID,这在小型实验里碰巧能用,但在生产网络里就非常危险。比如你新加了一个接口IP比原来的大,重启OSPF进程后Router-ID变了,所有邻居关系都重建一次,整个网络要振荡一遍,这在现网里是不可接受的。所以我所有设备都手动指定Router-ID,规则也很简单:核心交换机用1.1.1.1和1.1.1.2,汇聚交换机用1.1.1.11到1.1.1.14,这样看路由表的时候一眼就能认出是哪台设备。手动指定Router-ID还有一个好处,就是Loopback接口的稳定性。Loopback接口只要不手动shutdown就永远不会Down,用它做Router-ID比用物理接口地址稳定得多。
在H3C平台上配置Router-ID的命令是ospf 1 router-id 1.1.1.1,注意这里如果OSPF进程已经启动过,修改Router-ID后必须重启OSPF进程才能生效。我当时就在模拟器上遇到过这个问题,改了Router-ID之后邻居状态一直是Exchange,后来查了才知道是进程没重启。还有一个细节是Router-ID必须全局唯一,如果两台设备不小心配了一样的Router-ID,邻居状态会出现反复振荡,一会儿Down一会儿Full,排查的时候非常头疼。
2. OSPF基础配置与邻居建立要点
2.1 从一条network命令理解OSPF的区域宣告
配置OSPF的第一步是在每台设备上启动进程,然后进入区域宣告接口网段。H3C的命令格式如下:
[Core-1] ospf 1 router-id 1.1.1.1 [Core-1-ospf-1] area 0.0.0.0 [Core-1-ospf-1-area-0.0.0.0] network 10.0.0.0 0.0.0.3 [Core-1-ospf-1-area-0.0.0.0] network 192.168.10.0 0.0.0.255很多初学者不理解network命令后面的反掩码是什么意思。0.0.0.3其实是一个通配符掩码,0表示必须严格匹配,255表示这一位可以任意。所以10.0.0.0 0.0.0.3表示匹配10.0.0.0到10.0.0.3这个范围内的IP地址,正好覆盖一个/30的互联链路。192.168.10.0 0.0.0.255表示匹配整个/24网段。这里有一个我踩过的坑:network宣告的是接口所在网段,而不是具体接口IP,所以写反掩码的时候一定要算清楚范围。比如一个接口是10.0.0.1/30,你写network 10.0.0.1 0.0.0.3也能匹配上,但如果你写成network 10.0.0.0 0.0.0.255,就会把实际不存在的地址也宣告出去,容易引起路由混乱。
还有一个常见的错误是宣告范围过大。有些朋友图省事,直接在一个区域里宣告核心设备的所有网段,这在小实验里问题不大,但一旦区域划分复杂起来,就可能把本该属于Area 1的网段错误宣告进了Area 0,导致路由路径不符合预期。我这次的做法是:每台设备只宣告自己直连的网段,而且对应的区域编号必须和规划一致。核心交换机的互联地址和业务VLAN接口地址宣告在Area 0,汇聚交换机连接核心的上行接口和业务网段宣告在对应的非骨干区域。这样ABR的职责才清晰,区域间的路由传递才有逻辑可言。
配置完网络命令之后,要养成check的习惯。H3C上先看display ospf peer,确认邻居状态都变成Full;再看display ospf routing,确认路由表条目完整。我遇到过配置完全一样但邻居始终起不来的情况,后来用display ospf error查看才发现是Hello报文里的认证字段不匹配。OSPF邻居建立的本质就是双方发送Hello包,包里的参数必须协商一致,否则邻居关系永远卡在Down或Init状态。
2.2 邻居状态机和排障方法
OSPF的邻居状态机,从Down到Full一共经历七个状态:Down、Attempt、Init、2-Way、ExStart、Exchange、Loading、Full。平时我们最需要关注的其实是几个转折点。从Init到2-Way,说明双方已经在Hello包里看到了对方,双向通信建立;从2-Way到ExStart,开始选举DR和BDR,然后交换数据库描述报文;从Exchange到Loading,开始发送链路状态请求;最后到Full,说明LSDB同步完成。我测试时最喜欢用调试命令terminal debugging配合debug ospf packet来观察这些状态的切换,看到状态一步步往前走,心里的底就越来越足。
在这七个状态中最容易出问题的就是2-Way之前。下面这个表格是我整理的邻居建立常见问题,每一个都是我在实验中真实遇到过的:
| 故障现象 | 可能原因 | 排查命令 |
|---|---|---|
| 邻居卡在Down或Init | Hello间隔或Dead间隔不一致 | display ospf interface |
| 邻居卡在Init | 区域ID不一致或接口掩码不匹配 | display ospf interface |
| 邻居卡在ExStart/Exchange | 接口MTU不一致 | display ospf peer verbose |
| 邻居反复Down/Up | Router-ID冲突或认证配置错误 | display ospf error |
| 单边邻居 | 接口被防火墙或ACL过滤了组播报文 | display current-configuration |
一个特别隐蔽的问题是MTU不一致导致邻居卡在ExStart。OSPF会在数据库描述报文中携带接口MTU值,如果两端MTU不一致,会导致数据库同步永远无法完成,邻居状态就卡在Exchange那里。我这次实验里有一次把核心互联接口的MTU改成1400做了模拟测试,结果邻居状态就卡住了,改回1500后立刻恢复正常。排障思路其实很简单:先看display ospf peer的当前状态,再逐层检查接口参数、区域配置和过滤策略,问题基本都能定位。
3. 特殊区域的设计与ABR行为
3.1 什么样的区域适合配Stub,什么样的适合配NSSA
OSPF的区域类型直接影响LSDB的大小和路由表条目的多少。骨干区域Area 0是必须存在的,所有非骨干区域都必须和Area 0相连。如果不做任何特殊配置,每个非骨干区域都会收到来自其他区域的全部Type 3 LSA,以及来自ASBR的外部路由Type 5 LSA,区域内的设备要维护完整的外部路由信息,这在区域很大时浪费资源。
Stub区域的设计初衷就是过滤外部路由。Stub区域内部不允许存在ASBR,所以Type 4和Type 5 LSA都不会进入这个区域,ABR会向Stub区域内下发一条默认路由,让区域内的设备访问外部网络时直接走默认路由出去。但Stub区域有个限制:区域内不能引入外部路由,也不能存在ASBR,所以如果某个区域里有一台设备需要引入静态路由或者RIP路由,就不能配成Stub。
NSSA区域就是为解决这个限制而生的。NSSA区域允许区域内存在ASBR并引入外部路由,引入的路由以Type 7 LSA的形式在区域内传播,由NSSA的ABR转换成Type 5 LSA后通告到骨干区域。同时NSSA区域默认不接收来自其他区域的Type 5 LSA,ABR也可以下发默认路由。
这次实验里的区域划分是这样的:Area 1配置为Stub区域,因为该区域只有接入终端和服务器,不需要引入外部路由;Area 2配置为NSSA区域,因为该区域有一台边界设备需要引入一条指向出口设备的静态默认路由。两种区域的配置形成一个鲜明对比,可以直观地看到LSA类型的变化。
我特别想强调一个容易混淆的概念:Stub区域和Totally Stub区域的区别。普通Stub区域仍然会收到其他区域汇总过来的Type 3 LSA,只是过滤了Type 4和Type 5;而Totally Stub区域把Type 3、Type 4、Type 5全部过滤掉,ABR只下发一条默认路由。在H3C设备上,配置Totally Stub需要在区域视图下加stub no-summary参数。我测试的时候一开始只在Area 1配了stub,结果路由表里还是一大堆Type 3的明细条目,后来加上no-summary才看到干净的路由表。
3.2 特殊区域配置实验与LSA验证
以Area 1为例,H3C上的配置如下:
[Core-1] ospf 1 router-id 1.1.1.1 [Core-1-ospf-1] area 0.0.0.1 [Core-1-ospf-1-area-0.0.0.1] stub区域内的汇聚交换机也必须配置stub,因为Stub区域内的所有路由器必须有相同的区域配置,否则邻居关系无法建立。这个一致性要求我在实验中吃过亏,只改了ABR没改区域内的设备,结果整个区域的邻居全部Down掉,排查了半天才想起来两边都要配。
Area 2的NSSA配置稍微复杂一点:
[Core-2] ospf 1 router-id 1.1.1.2 [Core-2-ospf-1] area 0.0.0.2 [Core-2-ospf-1-area-0.0.0.2] nssa default-route-advertisedefault-route-advertise参数让ABR向NSSA区域内下发默认路由。如果不加这个参数,NSSA区域内的设备访问外部网络时就没有默认路由可用,因为Type 5 LSA默认被过滤掉了。而区域内的边界设备引入外部路由的配置,则在ASBR上单独做,比如import-route static加一个nssa相关的参数。
配置完成后我做了两个关键验证。第一是在Area 1内的汇聚交换机上执行display ospf lsdb,可以看到LSDB里只有Router LSA、Network LSA、Type 3的Summary LSA,还有ABR下发的默认路由,完全没有Type 4和Type 5。第二是在Area 2内的设备上执行同样的命令,能看到Type 7 LSA出现。对比两个区域的LSDB,对OSPF LSA类型的理解一下子就从抽象变具体了。
还有一个细节是NSSA的转发地址问题。Type 7转换成Type 5时,如果ASBR和ABR不在同一个网段,转出来的Type 5 LSA可能包含一个不可达的转发地址,导致其他区域的路由黑洞。我这次实验特意把ASBR和ABR放在了同一个互联网段里,就是为了避免这个问题。如果实际网络里两者跨网段,需要在ASBR上配置nssa translator-always之类的参数来确保转换行为稳定,具体参数不同厂商略有差异,务必以设备文档为准。
4. OSPF与MSTP、VRRP的联动配置
4.1 MSTP域配置与实例划分
二层这块的配置目标是:在存在冗余链路的接入层和汇聚层之间消除环路,同时让不同VLAN的流量走不同的物理链路,实现负载均衡。传统STP只有一棵生成树,所有VLAN共享同一条转发路径,另一个冗余链路被阻塞掉,资源浪费严重。MSTP通过实例把VLAN映射到不同的生成树,每个实例独立计算拓扑,让不同VLAN的流量走不同链路。
H3C设备上的配置如下:
[H3C] stp region-configuration [H3C-mst-region] region-name CAMPUS [H3C-mst-region] instance 1 vlan 10 to 20 [H3C-mst-region] instance 2 vlan 21 to 30 [H3C-mst-region] active region-configuration这里最关键的一点是,整个二层网络的所有交换机必须配置相同的域名称和VLAN实例映射关系,否则MSTP会把它们视为不同的域,生成树计算就会出问题。实际经验是,域名称最好在项目一开始就规划好,不要用设备默认的NULL名称,因为默认情况下所有没有配置过MSTP域的交换机都在一个默认域里,一旦你改了区域配置而另一台没改,两个域之间会通过边界端口互连,可能出现意外的阻塞端口。
实例划分完之后,还要在核心交换机上指定根桥。H3C的命令是stp instance 1 root primary,把核心交换机指定为实例的主根桥,另一台核心做备份根桥stp instance 1 root secondary。这样设计的好处是:终端访问网关的流量走汇聚到核心的路径,在二层拓扑上就能保证最优。如果不指定根桥,生成树的根桥选举可能选到接入层交换机上去,流量路径绕远,延迟和带宽都会受影响。
MSTP和OSPF的联动是我这次实验重点关注的地方。当MSTP阻塞或放开某条链路时,二层的物理拓扑发生变化,OSPF的三层邻居关系也会一起变化。我在实验里模拟了汇聚交换机到核心交换机的主链路故障,MSTP立刻把备份链路切换到转发状态,同时OSPF感知到链路Down掉,重新进行SPF计算,把路由下一跳切到备份链路上。整个过程如果配置得当,丢包只有几个,这在只做二层冗余不跑动态路由的网络里是做不到的,因为传统STP收敛要几十秒。
4.2 VRRP网关冗余与OSPF的联动调优
VRRP的作用是让多台路由器共用一个虚拟IP地址作为终端网关,正常情况下主设备转发数据,主设备故障时备份设备立即接管。配置相对简单,在两台核心交换机上分别配置:
[H3C-Core-1] interface Vlan-interface 10 [H3C-Core-1-Vlan-interface10] vrrp vrid 1 virtual-ip 192.168.10.254 [H3C-Core-1-Vlan-interface10] vrrp vrid 1 priority 120核心交换机2上配置同样的VRRP组,但优先级保持默认100,这样核心交换机1成为主设备,才是真正的转发网关。配置完VRRP之后,要检查display vrrp,确认主备状态正确,虚拟IP都能ping通。测试时最直接的方法是把主设备的Vlan接口shutdown,观察终端网关的转发是否无缝切换到备设备。
真正让实验变得有价值的,是把VRRP切换和OSPF路由联动起来。终端通过默认网关访问外部网络时,如果核心交换机1是主网关,那么终端发往外部的流量会先进核心交换机1,再由它根据路由表转发出去。如果核心交换机1到上层出口的路由不好,或者Cost值很大,流量就可能从核心交换机1穿到核心交换机2,再绕道上行,性能下降不说,还可能形成非对称路径。
我在实验里遇到的真实情况是:核心交换机1是VRRP主设备,但它到出口设备的OSPF Cost值没有调整,默认情况下所有环路接口Cost相同,OSPF就出现了等价路由,一部分流量从核心1走,一部分从核心2走。由于核心2不是主网关,从核心2出去的流量反而是由VRRP备份设备转发出去的,虽然功能上没问题,但路径不合理,而且排障时会让人困惑。解决办法是在核心交换机1的上行接口上用ospf cost命令把Cost值调小,让它成为出口流量的首选路径,核心交换机2的上行接口Cost调大作为备份。这样VRRP的主备状态和OSPF的路由路径就保持一致了:主网关的主设备同时也是出口流量的首选设备。
这套联动机制验证起来也很直观。我在终端上持续ping外网地址,然后手动切换VRRP主备,观察丢包情况和路由表变化。配置合理的情况下,丢包只有VRRP切换瞬间的那几包,OSPF重新收敛之后路由很快恢复。如果丢包时间很长,大多是因为OSPF的计时器配置不当,或者VRRP的抢占延时设置得过长。VRRP抢占延时我设成了5秒,这样备份链路稳定后再切换,避免因为链路闪断导致VRRP频繁震荡。
5. 综合验证与故障排查实录
5.1 全网连通性验证清单
实验做完不等于结束,系统性的验证才是判断配置正确与否的依据。我整理了一份验证清单,按顺序执行一遍,基本上全网状态就摸清了。
| 验证目标 | 使用命令 | 预期结果 |
|---|---|---|
| OSPF邻居状态 | display ospf peer | 所有邻居状态均为Full |
| 区域路由表 | display ospf routing | 各区域路由条目完整,默认路由正确下发 |
| LSA类型 | display ospf lsdb | Stub区域无Type 4/5,NSSA区域有Type 7 |
| MSTP实例状态 | display stp instance 1 | 根桥正确,端口角色符合预期 |
| VRRP状态 | display vrrp | 主备状态正确,虚拟IP可ping通 |
| 跨VLAN通信 | ping 192.168.20.1 | 不同VLAN终端可以互通 |
| 外部网络通信 | ping 出口设备接口地址 | 经OSPF转发路径正常,路由可达 |
| 主备切换测试 | shutdown核心1相关接口 | VRRP快速切换,OSPF重新收敛,丢包可接受 |
逐条执行清单的时候,我最关注的是OSPF路由表。display ospf routing看到的不只是路由条目,还能看到每条路由的下一跳和Cost值。比如业务网段192.168.10.0/24在核心交换机上看到的下一跳应该是对应汇聚交换机的互联地址,Cost值应该符合链路带宽的默认计算规则。如果下一跳走错方向,大概率是区域宣告错误或者Cost调整出了问题。
除了路由表,我还会在终端上做双向的tracert测试,从终端A到终端B、从终端A到出口设备、从出口设备回访终端。tracert能直观地看到报文经过的每一跳,如果路径和设计不一致,很快就能发现是哪个环节出了问题。特别要提醒的是,做完所有配置后一定要保存配置,H3C上是save force,不然模拟器或真机一断电全部配置就丢了。我实验时吃过这个亏,调好的配置忘了保存,重启后全部重来。
5.2 这次实验里踩过的5个真实坑
第一个坑是Router-ID没手动指定。实验初期有一台汇聚交换机没配Router-ID,设备自动选了一个接口IP地址作为Router-ID。后来我给这台设备增加了一个Loopback地址并宣告进OSPF,重启进程后Router-ID变成了新的Loopback地址,所有邻居关系全部重建,整网路由表刷了一遍,业务中断了十几秒。教训就是Router-ID必须手动规划,而且要选稳定接口的地址,不能依赖自动选举。
第二个坑是Stub区域配置不一致。我在Area 1的ABR上配了stub no-summary,但区域内的汇聚交换机只配了stub,结果ABR不向区域内下发Type 3 LSA,区域的默认路由也没生成,区域内所有设备的OSPF路由表几乎空了。因为ABR和区域内设备对区域类型的理解不一致,OSPF会认为这不属于同一个区域配置,有些设备直接中断了邻居关系。解决方法是保证特殊区域里所有路由器都配置相同的区域属性,配置完成后用display ospf brief逐台核对。
第三个坑是VRRP和OSPF的路径不一致。这个我在前面详细说过,主网关设备的上行Cost值没调优,导致一半流量从备份设备出去。当时排障时以为路由配置有问题,查了接口状态、区域配置都很正常,后来对照display ospf routing和实际转发路径才发现是等价路由的问题。这个坑在生产环境里特别容易踩,因为功能上网络能用,但性能不达标、排障困难,调优方法就是通过Cost值控制路径。
第四个坑是MSTP域名称不一致。我在模拟器里新增了一台接入交换机,在图省事的情况下没有配置MSTP域,直接启用了STP。结果这台交换机的端口变成了边界端口,域内的生成树实例拓扑被意外改变,部分VLAN的流量路径和预期不一致。排查时看display stp brief才发现其他交换机上的端口角色变了。最后在新增交换机上补齐了相同的MSTP域配置,拓扑才恢复正常。
第五个坑是OSPF计时器不匹配。我为了测试快速收敛,把核心互联接口的Hello间隔改成了5秒,Dead间隔保持默认40秒。另一端的接口还是默认的Hello间隔10秒,由于Hello报文中的参数不一致,邻居状态变得极不稳定,一会儿Up一会儿Down。OSPF的Hello和Dead计时器并不需要两端完全一致,但Dead计时器必须是Hello间隔的整数倍,所以我调整两边配置后邻居才稳定下来。实验环境下乱改计时器问题不大,生产环境一定要统一规划,否则排查成本非常高。
6. 写在实验之后
这个综合实验做下来,我最深的体会是:网络排障不能只看一个协议,要从整个数据转发的路径上去想问题。OSPF邻居正常不代表全网通畅,MSTP拓扑健康也不代表流量路径最优,VRRP主备状态正确更不代表网关转发一定没问题。三个协议叠加在一起,任何一个环节的配置偏差都可能导致最终用户体验上的丢包和延迟。我后来在真实项目中遇到的很多故障,根源往往不在某一个协议本身,而是协议之间的配合出了问题,比如VRRP切换和路由收敛的时序不一致,或者MSTP的拓扑变化没有及时反映到三层路由中。
最后再分享一个小建议:实验做完之后,把每台设备的配置导出存档,配合验证结果形成一份完整的报告。以后网络出现问题,翻配置记录比重新登录设备逐台排查要高效得多。我当时就是把每台设备的display current-configuration输出全部保存下来,和验证命令的输出放在一起归档,后来模拟器环境重置后恢复配置时派上了大用场。如果还想继续深入,可以在这个实验基础上加入OSPF认证、BFD快速检测、路由引入过滤等内容,把综合实验做成一个更完整的园区网演练项目。