冗長性の裏に潜むレイヤ2の呪縛:STPのBPDUフレーム構造と、パケットの生々しい挙動から読み解くループ回避の極意
ネットワークエンジニアなら誰もが一度は恐怖する「レイヤ2のブロードキャストストーム」。
冗長化のためにスイッチ同士を二重、三重に接続した瞬間、ARPリクエストやフローティングするパケットが無限のループを描き、CPU使用率が100%に張り付いて管理画面すら応答しなくなる――あの冷や汗が出るような瞬間を、あなたも経験したことがあるのではないだろうか。
現代のデータセンターや企業キャンパスネットワークにおいて、ゼロトラストアーキテクチャの浸透に伴い「境界防御」の概念はエッジからデバイス、そしてマイクロセグメンテーションへと移行している。しかし、その根底を支える物理的・論理的な基盤、すなわちOSI参照モデルの第2層(データリンク層)におけるループフリーの維持という命題は、イーサネットが生き続ける限り決して色褪せることはない。
今回は、このレイヤ2の秩序を守り続ける「守護神」、Spanning Tree Protocol(STP)の核心に迫る。特に、スイッチ間を駆け巡る制御パケットである BPDU(Bridge Protocol Data Unit) のフレーム構造を丸裸にし、彼らがどのようにしてトポロジを計算し、パケットの暴走を未然に防いでいるのか、そのディープな内部挙動を紐解いていこう。
—
1. パケットアナライザが暴くBPDUの正体:IEEE 802.1Dから始まる系譜
STPがやり取りするBPDUは、通常のデータフレームとは異なり、上位層のトランスポートプロトコル(TCP/UDP)の力を借りない。レイヤ2のデータリンク層上で直接、マルチキャストアドレス(01:80:C2:00:00:00)宛てに流れる純粋なイーサネットフレームである。
WiresharkなどのパケットキャプチャツールでこのBPDUをキャプチャすると、LLC(Logical Link Control)ヘッダーの直下に、IEEE 802.3の長さに似せたフィールド、そしてDSAP/SSAP(共に 0x42)、さらにControlフィールド(0x03)が続き、その後にSTP固有のペイロードが展開されるという、レガシーかつ美しい構造を目の当たりにすることができる。
STPには大きく分けて、Configuration BPDU(設定BPDU)とTCN(Topology Change Notification)BPDUの2種類が存在するが、今回はトポロジ計算の主役である Configuration BPDU の内部フィールド構造を詳細に分解していこう。
Configuration BPDUのフィールド構成
BPDUの全体像は、以下のような緻密なビット・バイトの集合体で構成されている。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Protocol ID (2 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Protocol Ver | Message Type | Flags | Root ID... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Root ID (cont.) | Root Path Cost |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Root Path Cost (cont.) | Bridge ID... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Bridge ID (cont.) | Port ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Age | Max Age |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Hello Time | Forward Delay |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
このフレームの中身を、現場のアーキテクトが知っておくべき実務的な視点で一つずつ解体する。
1. Protocol ID (2 bytes):
常に 0x0000(Spanning Tree Protocol)が格納される。
2. Protocol Version ID (1 byte):
IEEE 802.1Dなら 0x00、RSTP(IEEE 802.1w)なら 0x02、MSTP(IEEE 802.1s)なら 0x03 が入る。プロトコルの進化に伴い、このバージョン番号がスイッチ間のネゴシエーションの鍵を握る。
3. Message Type (1 byte):
0x00 がConfiguration BPDU、0x80 がTCN BPDUを示す。
4. Flags (1 byte):
最上位ビット(Bit 7)がTopology Change(TC)、最下位ビット(Bit 0)がTopology Change Acknowledgment(TCA)として機能する。RSTPでは、この1バイトのフラグ領域をフル活用して「Proposal/Agreement」ハンドシェイクを実現している。
5. Root Identifier (8 bytes):
現在のネットワーク(Spanning Tree)において、ルートスイッチ(根)であると自負している(あるいは推測されている)ブリッジのID。先頭2バイトがブリッジ優先度(Bridge Priority)、残り6バイトがMACアドレス。
6. Root Path Cost (4 bytes):
ルートスイッチに到達するまでに経費として累積されるパスコストの総額。リンクの帯域幅(10Mbpsなら100、100Mbpsなら19、1Gbpsなら4、10Gbpsなら2など、IEEE 802.1Dの旧規格基準)に応じて加算されていく。
7. Bridge Identifier (8 bytes):
このBPDUを生成・送信している「送信元スイッチ」自身のブリッジID(優先度 + MACアドレス)。
8. Port Identifier (2 bytes):
BPDUを送り出した物理ポートの識別子。上位4ビットがポートプライオリティ、下位12ビットがポート番号を示す。
9. Message Age / Max Age / Hello Time / Forward Delay (各2 bytes):
STPのライフサイクルを支配する極めて重要なタイマー値。
—
2. トポロジ計算プロセス:ブリッジIDとパスコストの「マインドゲーム」
スイッチが起動した瞬間、すべてのスイッチは「我こそがネットワークの頂点(ルートブリッジ)である」という強烈なエゴを抱き、自分自身のブリッジIDをルートIDに設定したBPDUを全ポートから吐き出し始める。
このBPDUの応酬こそが、スパニングツリーの収束(Convergence)に向けた壮大なマインドゲームの始まりである。
ルート選出のアルゴリズム(4つの基準)
ネットワーク全体で単一のルートブリッジを決定するために、スイッチは受信したBPDUと自身が保持する情報を以下の優先順位で厳格に比較する。
1. 最小の Root ID:
もっとも優先度が高く、かつMACアドレスが小さいスイッチをルートとして崇拝する。
2. 最小の Root Path Cost:
ルートブリッジまでの累積コストが最も低いパスを選択する。ここが、低速リンクが「Blocking(破棄)」状態に追いやられる主たる理由だ。
3. 最小の Sender Bridge ID:
同一コストのパスが複数ある場合、隣接するスイッチのブリッジIDが小さい方を優先する。
4. 最小の Sender Port ID:
同一スイッチに複数の物理リンク(チャネリング未設定時)で接続されている場合、送信元のポート番号が小さい方を選択する。
このアルゴリズムに基づき、各スイッチは「どのポートをRoot Port(ルートポート)にするか」「どのセグメントでどのポートをDesignated Port(代表ポート)にするか」を決定し、それ以外の不毛な冗長パスを Blocking State へと叩き落とす。
—
3. タイマー値の魔術:Message Age、Max Age、Hello Timeが引き起こすレイテンシーの罠
レガシーなSTP(802.1D)において、トポロジが変更された際や障害が発生した際の収束には、最大で50秒もの時間を要することがある。この遅延の元凶こそが、BPDUに刻まれているタイマー値の仕様である。
- Hello Time (デフォルト: 2秒):
ルートブリッジがBPDUを生成し、配下に送り出す間隔。
- Max Age (デフォルト: 20秒):
スイッチがルートブリッジからのBPDUを受信しなくなってから、「ルートとの接続が切れた」と判断するまでのタイムアウト時間。
- Forward Delay (デフォルト: 15秒):
ポートがBlocking状態からListening状態を経てLearning状態、そして最終的にForwading状態に至るまでの、各遷移段階(ListeningとLearningのそれぞれ)で待機する時間。$15秒 \times 2 = 30秒$ がここに費やされる。
現場で直面するトラブル:タイマーの誤設定と「サイレントデスカッション」
実務において、ディープな障害対応をしていると、このタイマー値の不一致が引き起こす奇妙な現象に遭遇する。
例えば、複雑なマルチベンダー環境や、トンネリング技術を挟んだレイヤ2延伸(VLAN over IP等)を行っている環境では、BPDUの転送遅延やドロップが発生する。
もし、Max Age(20秒)を超える遅延が発生すると、下位のスイッチは「ルートブリッジが死んだ」と誤認し、勝手に自らをルートだと宣言(Topology Changeの誘発)してトポロジの再計算を始めてしまう。これが頻発すると、ネットワーク全体がフラッピングを起こし、実パケットの転送が完全に停止する「スタック状態」に陥る。
インフラアーキテクトとして、レガシーSTPをそのまま放置することは、現代の高速なアプリケーション要件(ミリ秒単位の応答が求められるWebトランザクションや金融取引)の前では致命的な設計ミスと言わざるを得ない。
—
4. 実務で役立つ設定と最適化:RSTP/MSTPへの移行とエッジポート保護
では、このレイヤ2の呪縛から逃れ、ミリ秒単位での収束と強固なセキュリティを担保するにはどうすればよいのか。答えは明確だ。IEEE 802.1W(RSTP)やIEEE 802.1s(MSTP)への完全移行、そして適切なポートセキュリティの適用である。
以下に、Cisco Catalyst / IOS-XE環境を想定した、モダンかつ堅牢なSTP設定のベストプラクティスコードを示す。実務のコンフィグレーションにそのまま組み込んで活用してほしい。
! =====================================================================
! 1. スパニングツリーのモードをRSTP(Rapid PVST+)に変更
! レガシーな802.1Dを排除し、P/Aハンドシェイクによる高速収束を有効化
! =====================================================================
spanning-tree mode rapid-pvst
spanning-tree extend system-id
! =====================================================================
! 2. ネットワークの根(ルートブリッジ)を明示的に固定
! 勝手に選出されてトラフィックのフローが歪むのを防ぐ
! =====================================================================
spanning-tree vlan 10,20 priority 4096
! =====================================================================
! 3. エンドデバイス(PCやサーバー)が接続されるポートの保護
! PortFastを有効にし、さらにBPDU Guardを適用することで、
! 万が一ユーザーがスイッチを持ち込んで接続した際のループ暴走を物理的に遮断
! =====================================================================
interface Range GigabitEthernet 0/1 - 24
description === Access Ports for End-Hosts ===
switchport mode access
switchport access vlan 10
spanning-tree portfast
spanning-tree bpduguard enable
! =====================================================================
! 4. アップリンク側ポートの保護
! Root Guardを有効にし、外部の不正なスイッチが優位なBPDUを送りつけて
! ルートブリッジの座を奪う(Root Hijacking攻撃)のを阻止
! =====================================================================
interface GigabitEthernet 0/48
description === Uplink to Core Switch ===
spanning-tree guard root
セキュリティの視点:BPDU GuardとRoot Guardの重要性
ネットワークセキュリティの文脈において、STPは攻撃者にとって格好のターゲットになり得る。
悪意を持った攻撃者が、自前のPCや小型スイッチから意図的に「極端に低いプライオリティ(例: 0)」を設定したBPDUを社内ネットワークのアクセスポートに流し込んだ場合を想像してほしい。
スイッチは「新しい神(ルートブリッジ)が現れた」と勘違いし、トポロジを強制的に再計算する。その結果、正当なコアスイッチを経由していたトラフィックが攻撃者の端末へと強制的にバイパスされ、中間者攻撃(MitM: Man-in-the-Middle Attack) やトラフィックのブラックホール化が容易に成立してしまう。これが STPルートハイジャック攻撃 の脅威だ。
先ほどのコンフィグレーションで示した spanning-tree guard root や spanning-tree bpduguard enable は、単なる可用性向上策ではなく、ゼロトラストの思想に基づいた「レイヤ2境界における必須のセキュリティ要件」なのだ。BPDU Guardが有効なポートでBPDUを受信した場合、ポートは即座に err-disabled 状態へと落とされ、ネットワーク全体の汚染が物理的・論理的に隔離される。
—
5. 結びにかえて:パケットの裏側を愛するエンジニアへ
STPというプロトコルは、パケットの挙動を追う者にとって非常にロマンに満ちた存在である。たった数バイトのブリッジIDの大小、たった1ビットのフラグの変化が、何百台ものスイッチの運命を左右し、物理的なデータの流路をダイナミックに書き換える。
日々の運用の中で、show spanning-tree のコマンド結果を眺めるだけではなく、その背後でどのようなBPDUフレームが生成され、どのタイマーが刻まれ、どのポートが息を潜めているのかを脳内でパケット化してイメージできるかどうかが、優れたインフラアーキテクトと単なるオペレーターを分ける境界線となる。
レイヤ2の足元を固めること。それは、堅牢なセキュリティと極限のパフォーマンスを両立させた、真に信頼できるエンタープライズネットワークを築くための、最も確実で泥臭い第一歩なのだ。
コメント