SDNアプローチによるBGP経路監視を試してみる
「ネットワーク運用の自動化」として、BGP経路監視を考察してみたいと思います。
NetOpsCoding Advent Calendar 2015 12/12分のエントリーです
qiita.com
◾️ ”BGP運用”という言葉から想定されるイメージ
BGP運用というと、なんとなく「BGP職人さん」という言葉を連想してしまうのは、私だけでしょうか?
BGP職人さんは、事前に策定されたBGP運用ポリシーに従って、ポリシー・ルーティングに関わるルートマップ等コンフィグを投入することができる存在であり、想定どおり、ポリシー・ルーティングが動作されているかを確認するため、ベンダ固有のCLIコマンドを駆使して細かなBGP制御を確認することを日々の業務として実施する。
そんなイメージを、「BGP運用」からは、連想してしまいます。
さらに、不測な事態としてNWトポロジが安定動作していないことが判明した際には、BGP等プロトコル動作の振る舞いから、障害箇所を推測して、長年の運用経験から導き出された障害対策案の中からベストな方法で障害復旧を施すことができるネットワーク達人こそが、大規模ネットワーク運用を担っていることでしょう。
◾️ ”BGP職人の世界”に運用自動化のメスを入れるためには?
BGP職人の運用経験を踏まえた、運用の自動化を実現するには、
- 課題1「BGPコンフィグ設定通りに、BGP動作していることを、検証する仕組み」
- 課題2「実ネットワークでのBGP動作履歴を、オペレーション観点で、ログ管理できる仕組み」
- 課題3「BGP障害解析として、過去のBGP障害履歴から障害箇所を推定する仕組み」
が備わっているBGPシミュレーション機能を有する運用システムが必要になるのでしょう。
まずは、課題1「BGPコンフィグ設定通りに、BGP動作していることを、検証する仕組み」の解決方法と一つとして、End-End開通監視に着目した過去のSlideshareを共有しておきます。
www.slideshare.net
ここでのポイントは、従来のCLI, SNMPでのBGP監視では、リアルタイムな監視の実現が困難なので、BMPに着目してEnd-End開通監視のプロトタイプを実現しましたというネタになります。
◾️ SDNアプローチによるBGP経路監視を試してみる
前置きが長くなりましたが、ここからが本題です。
BGP経路監視ツール"bgpSimulator"の作成して、BGP経路監視の有効性を確認しました。
ちなみに、BGP経路監視には、BGPルータ側でのBMP機能が動作することを前提としております。
そこで、CSR1000v(IOS XE)を検証構成に配備しました。
(1) BGP経路監視ツール"bgpSimulator"
BGP経路監視ツール"bgpSimulator"は、”BMP処理部"と"BGPパス計算部"から構成されております。
前者は、Ryu BMP Serverを活用した実装コードになっております。また、後者は、Ryu BGPコードを改造して実現しております。
なお、動作としては、以下のような処理の流れによって実現しております。
1. まず、BGP経路監視ツール"bgpSimulator"の起動時に、CSR1000vのBGP構成をシミュレーション面として構築する
2. CSR1000vで、adj-RIB-inが変化したタイミングで、BGP UpdateメッセージをBMP情報として通知する
3. bgpSimulatorは、受信したBMP情報からBGP Updateメッセージを抽出する
4. bgpSimulatorは、"BGP1"のBGPシミュレーション面のadj-RIB-inに、BGP Ipdateメッセージを注入する
5. bgpSimulatorは、BGPシミュレーション面のadj-RIB-inの更新を契機に、BGPパス計算を行い、RIB-localに保持する
6. オペレータは、bgpSimulatorのコマンド上から、RIB-local情報を参照する
(2) BGP検証環境
全体のNWトポロジは、こんな感じです。CSR1000vは、BGP1の箇所に配備しております。
ちなみに、bgpSimulatorツールを起動した後に、"BGP6"ルータで、プレフィックス"172.16.0.0/24"を追加した上で、BGP経路監視の様子を確認しております。
(3) 動作結果の確認
まずは、bgpSimulatorツール起動後に、BMP情報を受信した様子を確認しておきます。
$ sudo ryu-manager bgpSimulator.py loading app bgpSimulator.py creating context wsgi instantiating app None of SimpleBGPSpeaker creating context bgps instantiating app bgpSimulator.py of BgpSimulator (3684) wsgi starting up on http://0.0.0.0:8080/ (3684) accepted ('127.0.0.1', 50301) ... (snip) BMP client connected, ip=192.168.100.1, port=14855 Start BMP session!! [192.168.100.1] Received BMPPeerUpNotification, peer=[10.0.0.1] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.0.1] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.0.1] Received BMPPeerUpNotification, peer=[10.0.1.2] Received BMPRouteMonitoring=[{'path_attributes': {'ORIGIN': '?', 'EXTENDED_COMMUNITIES': ['65010:101'], 'AS_PATH': [[65010]], 'MP_REACH_NLRI': {'nexthop': '192.168.101.101', 'nlri': [{'prefix': '192.168.2.0/24', 'label_list': [20], 'route_dist': '65010:101'}, {'prefix': '172.16.0.0/24', 'label_list': [22], 'route_dist': '65010:101'}]}}, 'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_Update'}], peer=[10.0.0.1] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.0.1] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.0.1] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.2] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.2] Received BMPPeerUpNotification, peer=[10.0.1.3] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.2] Received BMPRouteMonitoring=[{'path_attributes': {'ORIGIN': '?', 'MP_REACH_NLRI': {'nexthop': '192.168.104.102', 'nlri': [{'prefix': '192.168.2.0/24', 'label_list': [20], 'route_dist': '65010:101'}, {'prefix': '172.16.0.0/24', 'label_list': [22], 'route_dist': '65010:101'}]}, 'AS_PATH': [[65010]], 'MULTI_EXIT_DISC': 0, 'LOCAL_PREF': 100, 'EXTENDED_COMMUNITIES': ['65010:101']}, 'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_Update'}], peer=[10.0.1.2] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.2] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.3] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.3] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.3] Received BMPRouteMonitoring=[{'path_attributes': {'ORIGIN': '?', 'MP_REACH_NLRI': {'nexthop': '192.168.105.102', 'nlri': [{'prefix': '192.168.1.0/24', 'label_list': [18], 'route_dist': '65010:101'}]}, 'AS_PATH': [], 'MULTI_EXIT_DISC': 0, 'LOCAL_PREF': 100, 'EXTENDED_COMMUNITIES': ['65010:101']}, 'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_Update'}], peer=[10.0.1.3] Received BMPRouteMonitoring=[{'received_time': '2015/12/10 23:33:44', 'message_type': 'BGP_RouteRefresh'}], peer=[10.0.1.3]
さらに、CSR1000v上のBGPテーブルと、bgpSimulatorル上のBGPテーブルを比較してみます。
CSR1000v上のBGPテーブル
BGP1>show bgp vpnv4 unicast all BGP table version is 68, local router ID is 10.0.1.1 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, x best-external, a additional-path, c RIB-compressed, Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 65010:101 *> 172.16.0.0/24 192.168.101.101 0 65010 ? * i 192.168.104.102 0 100 0 65010 ? *>i 192.168.1.0 192.168.105.102 0 100 0 ? *> 192.168.2.0 192.168.101.101 0 65010 ? * i 192.168.104.102 0 100 0 65010 ?
bgpSimulator上のBGPテーブル
$ ./get_rib.sh Status codes: * valid, > best Origin codes: i - IGP, e - EGP, ? - incomplete Network Labels Next Hop Reason Metric LocPrf Path *> 65010:101:192.168.2.0/24 [20] 192.168.101.101 ASN 65010 ? * [20] 192.168.104.102 0 100 65010 ? *> 65010:101:172.16.0.0/24 [22] 192.168.101.101 ASN 65010 ? * [22] 192.168.104.102 0 100 65010 ? *> 65010:101:192.168.1.0/24 [18] 192.168.105.102 Only Path 0 100 ?
CSR1000vのBGPテーブルと、bgpSimulatorのBGPテーブルは、同じBGPパス情報を保持しています。
(4) BGP Peerダウン時の動作結果の確認
今度は、BGP4〜1BGP1との間のBGP Peerがダウンさせてみます。
bgpSimulatorツールを起動したターミナル上には、BMPPeerDownNotificationを受信した旨が表示されます。
$ sudo rya-manager bgpSimulator.py ... (snip) Received BMPPeerDownNotification, peer=[10.0.0.1]
つづいて、CSR1000v上のBGPテーブルと、bgpSimulatorル上のBGPテーブルを比較してみます。
CSR1000v上のBGPテーブル
CSR1000vのBGPテーブルでは、BGP4〜1BGP1との間のBGP Peerがダウンに基づき、BGPパス再計算が行われたため、nexthopが変化している様子がわかります。
BGP1>show bgp vpnv4 unicast all BGP table version is 70, local router ID is 10.0.1.1 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, x best-external, a additional-path, c RIB-compressed, Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 65010:101 *>i 172.16.0.0/24 192.168.104.102 0 100 0 65010 ? *>i 192.168.1.0 192.168.105.102 0 100 0 ? *>i 192.168.2.0 192.168.104.102 0 100 0 65010 ?
bgpSimulator上のBGPテーブル
一方、BGP経路監視ツール"bgpSimulator"では、”PeerDownNotification”を受信した場合ても、BGPパス再計算を実施するようには実装しておりません。
よって、 bgpSimulatorのBGPテーブルは、BGP4〜1BGP1との間のBGP Peerがダウン前のBGPパス情報からnexthopの変化は観測されません。
$ ./get_rib.sh Status codes: * valid, > best Origin codes: i - IGP, e - EGP, ? - incomplete Network Labels Next Hop Reason Metric LocPrf Path *> 65010:101:192.168.2.0/24 [20] 192.168.101.101 ASN 65010 ? * [20] 192.168.104.102 0 100 65010 ? *> 65010:101:172.16.0.0/24 [22] 192.168.101.101 ASN 65010 ? * [22] 192.168.104.102 0 100 65010 ? *> 65010:101:192.168.1.0/24 [18] 192.168.105.102 Only Path 0 100 ?
BGP Peerダウンが発生すると、CSR1000vのBGPテーブルと、bgpSimulatorのBGPテーブルは、同じBGPパス情報を保持しないという特徴をうまく活用してあげれば、BGP経路監視の観点で、早期にBGP障害を検知することが可能になるかもしれません。
以上より、BGP動作履歴を管理するには、BMPが有効であることが確認できました。
◾️ おまけ編:BGP経路監視ツール"bgpSimulator"をお手軽に試してみる
CSR1000vなどの実際のBGPルータを配備して、NWトポロジを構築するのは、なかなか手間がかかる話です。
RyuBGPには、BMP Client機能を有しているので、RyuBGPを活用して、BGP/MPLS-VPN面を構築した上で、もっと、手軽にBGP経路監視ツール"bgpSimulator"の動作を試してみることができるように、dockerコンテナでの実験環境を用意しました。
"README.md"通りに環境準備してもらえれば、BGP経路監視の動作イメージを体感してもらえると思います。
github.com