接口没配 BPDU 保护,端口为什么还是被关了?
一句话结论:核心交换机全局开启了
spanning-tree portfast bpduguard default,而面向下联交换机的 trunk 口在缺省开启的边缘端口自动识别(autoedge)中被判成了”边缘口”;一次约 3 秒的物理瞬断让下联交换机短暂成为根桥,链路恢复后它发出的第一个 BPDU 正好落在核心 3 秒判定窗口之后,端口被 BPDU Guard 直接 error-disabled不是环路,是**“面向交换机的口被当成了接终端的口”**
| 维度 | 信息 |
|---|---|
| 设备 | 锐捷 RG-S7800C(核心)× 2,H3C S5130S(接入) |
| 关键配置 | spanning-tree portfast bpduguard default + autoedge 缺省开启 |
| 触发条件 | 互联链路约 3 秒物理瞬断 |
| 结局 | Gi2/6 error-disabled,下联失联,需人工恢复 |
| 性质 | 定时炸弹,不是偶然事件 |
一、故障现象
某日 13:10,二级分行核心 0A(CORE-0A,锐捷 S7800C) 与下联接入交换机 SW-23(H3C S5130S) 的互联链路 Gi2/6 ⇄ Gi1/0/48 发生瞬断;链路恢复后,核心把 Gi2/6 置为 error-disabled,下联交换机上联中断、管理 VLAN 399 失联,核心产生 BPDU Guard 告警
现场第一反应是”这个口是不是配了 BPDU 保护”——结果翻接口配置,什么都没有:
interface GigabitEthernet 2/6
description To_ACCESS_SW23
switchport mode trunk
switchport trunk allowed vlan only <业务 VLAN、管理 VLAN 399、预留段>
没有 spanning-tree portfast,没有 spanning-tree bpduguard enable,没有 bpdufilter。看起来”什么都没配”,但端口就是被关了
文中设备名、接口描述与地址已做脱敏,VLAN 列表做了简化,不影响结论
二、拓扑与关键参数
graph TB
subgraph CORE["核心层"]
A["CORE-0A · RG-S7800C · RGOS 11.0(4)<br/>STP 根桥 · priority 0<br/>全局 portfast bpduguard default"]
B["CORE-0B · RG-S7800C<br/>priority 4096<br/>同样开启全局 BPDU Guard"]
A ---|"AggregatePort 1(同一隐患)"| B
end
A ==>|"Gi2/6 · trunk<br/>无 portfast、无 bpdufilter"| S["SW-23 · H3C S5130S-54S-HI-G<br/>Comware 7.1.070 · priority 8192<br/>stp bpdu-protection"]
S -->|"GE1/0/36 · VLAN 401"| T1["接入口"]
S -->|"GE1/0/40 · VLAN 440"| T2["接入口"]
S -->|"GE1/0/45 · VLAN 460"| T3["接入口"]
S -.->|"XGE 1/0/53-54 · shutdown"| X["备线(未启用)"]
| 设备 | 型号 / 版本 | STP 角色 | 关键配置 |
|---|---|---|---|
| 核心 0A | 锐捷 RG-S7800C,RGOS 11.0(4) | 根桥,priority 0 | spanning-tree portfast bpduguard default |
| 核心 0B | 锐捷 RG-S7800C | 非根,priority 4096 | 同样开启全局 BPDU Guard |
| 接入 SW-23 | H3C S5130S-54S-HI-G,Comware 7.1.070 | 非根,priority 8192 | stp global enable、stp bpdu-protection、接入口 stp edged-port |
互联链路为 trunk,双方放通 VLAN 399/401/410/440/460/999;SW-23 的 Gi1/0/48 没有配 stp edged-port,它本身不是边缘口
三、现场证据
3.1 核心侧:全局开了保护,接口上却看不到
spanning-tree portfast bpduguard default ← 全局 BPDU 保护
spanning-tree mst 0 priority 0 ← 0A 是根桥
spanning-tree
核心没有配置 spanning-tree portfast default,Gi2/6 也没有 portfast。也就是说:没有任何人把这个口”手工”配成边缘口
3.2 下联侧:日志把时间线交代得很清楚
13:10:35.050 Gi1/0/48 物理 down;13:10:35 Vlan-interface399 down
13:10:38.211 Gi1/0/48 物理 up; 13:10:38 Vlan-interface399 up
13:10:43.292 STP_NOT_ROOT:The current switch is no longer the root of instance 0
13:10:43.293 Gi1/0/48 进入 forwarding;检测到拓扑变化(TC)
13:10:44.205 Gi1/0/48 再次物理 down;Vlan-interface399 down
13:18:34 NTP 源丢失(隔离后的连带影响)
STP_NOT_ROOT 是关键:它说明在 13:10:43 之前,这台接入交换机曾经把自己当成根桥——而它之所以会发 BPDU,正是因为这件事
3.3 核心侧的告警
%SPANTREE-BLOCK_BPDUGUARD: Received BPDU on port GigabitEthernet 2/6
with BPDU Guard enabled. Disabling port.
配套的 show interfaces status err-disable 中,Gi2/6 的 Reason 为 BPDU Guard。核心配置里没有 errdisable recovery,所以这个口不会自愈,会一直保持 DOWN,直到人工恢复
四、根因:三个条件叠加
4.1 机制:全局保护 + 自动边缘端口
锐捷 RGOS 11.0(4) 的配置指南在 BPDU Guard 一节写得很明确:
可以在全局模式中用
spanning-tree portfast bpduguard default打开全局的 BPDU Guard 状态,在这种状态下,如果某个 Interface 打开了 Port Fast,或该接口自动识别为边缘口,而该 Interface 收到了 BPDU,该端口就会进入 Error-disabled 状态
而”边缘端口自动识别(autoedge)“在锐捷上是缺省开启的:指派口在 3 秒内收不到下游 BPDU,就判为边缘口,直接进入 Forwarding;一旦收到 BPDU,再自动识别为非边缘口
于是 Gi2/6 的处境是:
- 它是核心的指定口(核心是根桥,根桥所有端口都是指定口)
- 下联交换机是非根,它的根端口只收不发配置 BPDU,所以
Gi2/6在日常状态下收不到对端 BPDU - 因此
Gi2/6会被 autoedge 判成边缘口,并被全局 BPDU Guard 管辖
接口下没有配置,不代表没有行为——保护在全局,边缘口来自自动识别
4.2 触发:一次约 3 秒的物理瞬断
13:10:35 链路物理 down,13:10:38 恢复。这个 down 不是保护造成的:核心没有开 errdisable recovery,被 Guard 关掉的口不会 3 秒后自愈;它自愈了,说明这次是真断了一下
瞬断期间,接入交换机失去了核心的 BPDU,也就失去了根信息。按 STP 规则,它会以自身为根桥继续工作,并在链路恢复后向所有指定口发送 BPDU
4.3 竞态:3 秒判定窗口 vs 约 5 秒的 STP 收敛
这是整件事最”巧”、也最必然的地方:
| 时间 | 发生了什么 |
|---|---|
| 13:10:35 | 链路 DOWN,端口状态被清空 |
| 13:10:38 | 链路 UP,核心开始 autoedge 的 3 秒判定窗口 |
| 13:10:38 ~ 13:10:43 | 接入交换机还在 STP 收敛(13:10:43 才 Forwarding),尚未发出 BPDU |
| 约 13:10:41 | 3 秒窗口到期,核心判定 Gi2/6 为边缘口 |
| 约 13:10:43 | 接入交换机作为”临时根桥”,第一个 BPDU 到达 Gi2/6 |
| 约 13:10:44 | 边缘口收到 BPDU → BPDU Guard 触发 → Gi2/6 进入 error-disabled |
也就是说:闪断同时制造了”判定窗口”和”对端 BPDU”,而对端的 STP 收敛(约 5 秒)比核心的判定窗口(3 秒)慢了 2 秒,于是核心先把它认成”接终端的口”,随后 BPDU 一到就被当成非法报文处理掉了
换一种说法:如果对端能在 3 秒内发出 BPDU,这个口就不会被判定为边缘口,也就不会被关;如果链路不断,对端永远是非根、永远不发 BPDU,这个口就永远”安全”。两个条件同时成立,事故才发生
4.4 为什么之前半年都没事
因为 BPDU Guard 一直在等一个平时永远不会来的 BPDU:
- 稳态下,接入交换机是根端口,根端口不发配置 BPDU
- 核心
Gi2/6收不到 BPDU,autoedge 把它判成边缘口,但没有任何 BPDU 来”踩雷” - 这颗雷就这样安静地埋着,直到某一次链路瞬断——这是定时炸弹,不是偶然事件
五、排除环路
现场很容易怀疑”是不是下联环路导致 BPDU 绕回”,但证据不支持:
- 接入交换机只有
Gi1/0/48一条上联,XGE 1/0/53/54两条 trunk 均为 shutdown GE1/0/47是access vlan 999+stp edged-port+dot1x的稽查接入口,不是上联- 在用的
GE1/0/36/40/45分属 401/440/460 三个不同 VLAN,每个 VLAN 仅 1 个 up 口,不存在同 VLAN 双上行 - 下联日志里的
STP_NOT_ROOT说明 BPDU 是它自己发的(它曾短暂自认根桥),不是核心自己的 BPDU 绕回来 - 核心侧
Gi2/6是唯一连接该接入交换机的链路,且双方 trunk 放通的 VLAN 完全对齐
结论:不是环,是”瞬断 + 边缘端口竞态”
六、为什么别的 trunk 没中招
现场还有个有意思的对照:核心 0B 的同类型 trunk、以及 0A 的 AggregatePort 1,PortOperAutoEdge 和 PortBPDUGuard 都是 Disabled
这恰恰说明 autoedge 的运行态不是”持续轮询”,而是按链路事件判定并保持:端口在一次链路 UP 时如果见过 BPDU,就会被判为非边缘口并锁定;之后对端即使不再发 BPDU,它也不会自动变回边缘口
所以:
- 那些口”没事”,是因为它们上次链路 UP 时恰好见过 BPDU(例如对端核心在自身重启/倒换期间短暂当过根)
Gi2/6“有事”,是因为这次 UP 时,3 秒内确实没等到 BPDU
当前不是边缘口 ≠ 永远安全:下一次链路翻转,如果对端 STP 收敛再次超过 3 秒,同样的连环还会重演。尤其 AggregatePort 1——它是核心互联链路,一旦被 Guard 关掉,就是双核心隔离 + VRRP 双主,后果比一条下联严重得多
七、处置与整改
7.1 恢复端口
configure terminal
interface GigabitEthernet 2/6
shutdown
no shutdown
end
若配置了 errdisable recovery,也可以用 errdisable recovery 手动恢复;本次核心没有配,必须手动
7.2 把”面向交换机”的 trunk 从边缘口语义里摘出来
configure terminal
interface range GigabitEthernet 2/6-2/7,GigabitEthernet 1/11-1/12,AggregatePort 1
spanning-tree portfast disabled
spanning-tree autoedge disabled
spanning-tree bpduguard disabled
end
- 不要动全局
spanning-tree portfast bpduguard default:它对真正的接入口(核心Gi2/1~2/5这类 access + portfast 的口)是合适的,保护应该保留 - 只要 trunk 不再是边缘口,全局保护就管不到它;再在接口上显式关闭 guard,是双保险
7.3 同类隐患清单
核心上还有几条”面向交换机、没有 bpdufilter、会被 autoedge 判定”的 trunk,需要一并处理:
| 接口 | 描述 | 风险 |
|---|---|---|
Gi2/6 | 下联接入 SW-23 | 本次故障口 |
Gi2/7 | 同 VLAN 备份链路 | 与 2/6 完全相同的隐患 |
Gi1/11、Gi1/12 | 备份链路 | 同样的”无 filter trunk” |
AggregatePort 1 | 核心互联 | 风险最高,一旦触发就是双主 |
另外两条建议:
- 接入交换机
stp instance 0 priority 8192可以抬到 32768/40960,降低它作为”第二顺位根候选”的资格;治本仍靠核心侧关闭 autoedge/guard,优先级只是加固 - 继续排查 13:10:35 那次瞬断的物理原因(线缆、电口、CRC、接头),否则换个口还会再来一次
7.4 验证
show spanning-tree interface GigabitEthernet 2/6
show interfaces status err-disable
show spanning-tree
预期:PortAdminPortFast、PortOperAutoEdge、PortBPDUGuard 均为 Disabled;端口为 designated/forwarding;err-disable 列表为空;根桥仍是核心 0A
八、复盘 Takeaway
- “接口下没有配置”不等于”没有行为”。全局开关、缺省开启的特性、端口模板,都会绕过接口视图
- autoedge 缺省开启,是这套网络里最隐蔽的坑之一。面向交换机的 trunk 不能靠”我没配 portfast”来证明安全
- BPDU Guard 只该用于终端接入口。接交换机的口一旦被 autoedge 判成边缘口,保护就变成了”等一个迟早会来的 BPDU”
- 瞬断是触发条件,不是根本原因。根因是”边缘口语义 + 全局保护”同时压在了这条 trunk 上;物理闪断只是扣动了扳机
- 判断”谁关的口”,先分清
err-disable和链路 DOWN:被保护关掉的口不会自愈(除非配置了恢复),能 3 秒后自己起来的,一定是物理闪断 - 排查顺序:先看
err-disable的 Reason,再看全局配置,再看端口运行态(PortOperAutoEdge/PortBPDUGuard),最后才看接口配置
附录:排查命令清单
锐捷(核心)
show interfaces status err-disable # 违例原因
show logging | include BPDUGUARD # 告警原文
show running-config | include bpduguard # 全局保护
show running-config | include portfast
show running-config interface GigabitEthernet 2/6 # 接口配置
show spanning-tree interface GigabitEthernet 2/6 # 运行态字段
show spanning-tree # 根桥与端口角色
show interfaces counters # 物理层错包
H3C(接入)
display stp
display stp brief
display interface GigabitEthernet 1/0/48
display logbuffer
display current-configuration interface GigabitEthernet 1/0/48
文中拓扑、时序与配置均来自现场采集与配置备份对比,关键日志已做脱敏处理
