BGP Monitoring Protocol を RFC とパケットキャプチャで勉強してみた

はじめに

この記事は BBSakura Networks Advent Calendar 2024 の 21 日目の記事です。

こんにちは! BBSakura で基盤となるネットワークを開発している酒井です。

昨年の BBSakura Advent Calender では BGP Flow Spec について書いていました。今年も去年と同様に BGP ネタで書いていこうと思います。

今年の BGP ネタとしては、 BGP Monitoring Protocol (以降は BMP と呼びます)について RFC 7854 を読んで内容を理解し、実際にパケットキャプチャをして中身を眺めてみます。

BMP とは簡単に言うと、 BGP セッションの状態や交換される経路情報を効率的に収集するためのプロトコル になります。

過去には、JANOG 33.53452 でも解説されていますので、興味のある方はこれらも確認するとよいかと思います。

本記事では私が学習した内容について書いていきます。

RFC 7854

BMP は 2016 年に RFC 7854 が発行されて仕様が決定しました。その後、現時点で RFC 8671 (Adj-RIB-Out への拡張) ・ RFC 9069 (Loc-RIB への拡張) ・ RFC 9515 (BMP に関わる一部の IANA レジストリ登録ポリシーの変更) によってアップデートされています。ただ、これらの RFC のアップデート内容はあくまで拡張がメインであり、 BMP の基礎をおさえるのであれば RFC 7854 を読めば OK です。

RFC 7854 の導入部分であるセクション 1 には、 BMP の概要について次のように書かれています。

BMP provides access to the Adj-RIB-In of a peer on an ongoing basis and a periodic dump of certain statistics the monitoring station can use for further analysis. 
From a high level, BMP can be thought of as the result of multiplexing together the messages received on the various monitored BGP sessions.

Adj-RIB-In は BGP-4 プロトコル自体の RFC である RFC 4271 で定義されており、ローカルの BGP スピーカーがピア先より受信した経路情報のことです。つまり、 BMP はこの受信した経路情報を解析するために、ダンプ情報としてエクスポートをすることを目的としている、と言えるかと思います。あくまで、 BMP 自体はルータなどの BGP スピーカーの情報をエクスポートするための技術であり、情報の解析・収集を行なうコレクタ( monitoring station )は別に用意する必要があるわけです。

BMP で観測・提供できるものとして、 BMP Messages がセクション 3.1 で定義されています。

Message Type番号 メッセージ内容
Route Monitoring (RM) 0 ピアから受信した経路情報 (初回ダンプ後の ongoing な update を含む)
Stats Reports (SR) 1 ongoing な統計情報
Peer Down Notification 2 ピアダウンの情報
Peer Up Notification 3 ピアアップの情報
Initiation 4 BMP セッションを開始する時に通知 (BGP スピーカーのベンダー、ソフトウェアバージョンなどの情報通知)
Termination 5 BMP セッションを終了する時の通知
Route Mirroring 6 BGP スピーカーが受信した BGP メッセージをそのまま複製して送信

これらの BMP Messages はセクション 4 で定義されたフォーマットで BGP スピーカーからコレクタへ送信されます。なお、この BMP の通信は TCP で行なわれます。

セクション 4 のフォーマットの詳細はボリュームがあるため割愛しますが、 Per-Peer Header が定義されており、 BGP スピーカーから見たピア単位での情報の観測が可能です。

セクション 5 では、 BMP でもっとも使用されるであろう Route Monitoring の動作について解説されています。 BGP スピーカーとコレクタ間で BMP セッションがアップした直後に、まずはその時点での各ピアごとの Adj-RIB-In がダンプされて Route Monitoring メッセージが送信されます。その後は、新たにピアから Update を BGP スピーカーが受信すると、随時コレクタへその分の Route Monitoring メッセージを送信します。また、 Adj-RIB-In がポリシーやフィルター適用前か適合後のものかを表す Per-Peer Header 内の L フラグによって、 Route Monitoring メッセージは判別されるともセクション 5 では書かれています。

続く、セクション 67 ではそれぞれ Route Mirroring と Stat Reports の動作ついて簡単に触れられていますので、興味のある方は確認してみてください。

また、セクション 11 の Security Considerations では、 BMP 自体には認証などの機能がないことから、セキュリティ上の懸念がある場合は BGP スピーカーとコレクタ間の通信に IPSec を使用することを推奨しています。

パケットキャプチャ

ここまで RFC 7854 の内容について説明してきました。次からは実際の動作をパケットキャプチャしながら見ていきます。

環境の構築

今回は BGP スピーカーとして GoBGP、 BMP コレクタソフトウェアとして goBMP を使用します。

今回は BMP のパケットをキャプチャすることを目的にしているので、下図のように 2 つの GoBGP 間で BGP の Update を発生させて、その結果を goBMP 側で見てみましょう。

左からgoBMP、AS65001のGoBGP、AS65002のGoBGPと順に接続されている環境構成図。
環境構成図

GoBGP はバージョン 3.32.0 を使用しています。 GoBGP をインスール後に gobgpd -f <設定ファイル> & で次の内容の設定ファイルを読み込ませます。

[AS65001 GoBGP]

[global.config]
  as = 65001
  router-id = "192.168.110.1"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.110.2"
    peer-as = 65002

[[bmp-servers]]
  [bmp-servers.config]
    address = "192.168.10.70"
    port=5000
    route-monitoring-policy = "post-policy"
    statistics-timeout = 30

[AS65002 GoBGP]

[global.config]
  as = 65002
  router-id = "192.168.110.2"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.110.1"
    peer-as = 65001

これで 2 台の GoBGP 間の BGP ピアが Up するはずです。

続けて、 goBMP をビルド して、バイナリを ./bin/gobmp --dump=console で実行します。 このコマンドではポート番号を指定していないので、 goBMP はデフォルトの 5000 番の TCP ポートを使用していることになります。

これで環境は整いました!とても簡単に環境構築ができますね。

パケットキャプチャ結果

ここから実際に BMP 通信のパケットをキャプチャして Wireshark で見ていきます。今回のパケットキャプチャは goBMP 側で取得しています。注意点として、今回の環境だと BMP コレクタは TCP 5000 番ポートで BMP 通信のパケットを待ち受けていますが、この状態でパケットキャプチャした pcap ファイルを Wireshark で確認しても、別のプロトコル ( RSL ) として認識されており正しくデコードされません。そのため、 Wireshark では当該パケットエントリで右クリック→[Decode as...]の設定画面から BMP を選択して、正しくデコードする必要があります。

最初に BGP スピーカーとコレクタ間の BMP 通信の TCP コネクションが確立した直後に発行される Initiation Message を見ます。

Wireshark画面でのBGP Monitoring Protocolパケットでタイプがinitiation Messageのキャプチャのスクリーンショット。
BMP 通信開始時のパケットキャプチャ

sysName で BGP スピーカーが GoBGP であること、 sysDescr で GoBGP のバージョンが 3.32.0 であることの情報がエンコードされています。

次に BGP ピアがアップ/ダウンした時を見ていきます。具体的には AS65002 側の GoBGP を起動/停止して BGP ピアをアップ/ダウンさせてみます。

BGP ピアがアップした時の BMP 通信パケットでは Peer Up Notification が発行されていることがわかります。

Wireshark画面でのBGP Monitoring ProtocolパケットでタイプがPeer Up Notificationのキャプチャのスクリーンショット。
BGP ピアアップ時のパケットキャプチャ

Per Peer Header からピア先の情報もわかりますし、アップしたピア間の情報が GoBGP 間でやり取りされた BGP OPEN Message として格納されていてわかりやすいです。

続けて、下の図が BGP ピアダウンした時の Peer Down Notification です。

Wireshark画面でのBGP Monitoring ProtocolパケットでタイプがPeer Down Notificationのキャプチャのスクリーンショット。
BGP ピアダウン時のパケットキャプチャ

NOTIFICATION Message から、ピアダウンした理由が読み取れます。このように実際の BGP のメッセージが情報として付いてくるのは嬉しいですね!

次に実際に BGP Update のやり取りが GoBGP 間で発生した時の BMP パケットを見てみます。 AS65002 から gobgp global rib add 192.0.2.X/32 で Prefix を 5 個ほど広報してみます。

Wireshark画面でのBGP Monitoring ProtocolパケットでタイプがRoute Monitoringのキャプチャのスクリーンショット。
BGP Update 発生時のパケットキャプチャ

Route Monitoring が発行され、実際に今回 GoBGP 間でやり取りされた BGP Update Message も含まれています。

これによって定期的に発行される Stats Reports でも BGP スピーカーが受信した Adj-RIBs-In の Prefix 数 ( Number of routes )が 5 にカウントされていました。

Wireshark画面でのBGP Monitoring ProtocolパケットでタイプがStatistic Reportのキャプチャのスクリーンショット。
定期的に発行される Stats Report のパケットキャプチャ

正しく統計情報も反映されていそうです!

以上となります。

おわりに

今回の記事では RFC 7854 とパケットキャプチャを通した BMP の調査内容について書きました。 BGP の定点監視を可能にするプロトコルが正式に定義されていて、実装がちゃんとあることは全世界の BGP オペレータにとって喜ばしいことですね!

BBSakura Networks Advent Calendar 2024 もそろそろ終盤ですが、引き続きお楽しみください。

来年のアドベントカレンダーでも BGP ネタで書きたいな〜。