BGP Route Injection Tool(2)

前回の続き

今回は「実際にインターネットで交換されているデータをもらってきて注入する」です。

Route Views Project というところで経路情報の定点観測と各時点の経路情報ダンプの公開を行っています。そこで公開している経路データをもらってきて注入します。以下、

  • 経路データの変換ツール
    • bgpdump
    • bgpparser
  • 変換した経路情報の注入
    • bgpsimple

を使います。

(前回同様、ログとかの日付がばらばらですが、日を開けて合間合間でやってためたログをつなぎ合わせているからです。日付はあまり気にしないでください。)

経路データの準備

RouteViews でどこか適当なところからデータをもらってきます。データは MRT 形式のデータとなっています。(以降 WIDE/DIXIE のデータを使っています。)

準備(開発系ツール)

今回割とコンパイルしてインストールするので、その辺の基本的なツール類はあらかじめ入れておきましょう。gcc, g++, libtool, autoconf, make, automake, autotools-dev あたりは当然必要になります。

MRT format について

MRT format はMRT というルーティングツールで使用されていたデータ形式ですが、MRT 自体は 2000 年あたりで開発が止まっていて、データ形式が zebra/quagga などで引き継がれて生き残ってきました。ちなみに MRT は debian では lenny までパッケージが残っていましたが、squeeze からはなくなってしまいました。*1

MRT format ですが、4-byte AS 番号の対応にあわせてバージョンがあります。RouteViews で配布されている MRT データを読む場合は TABLE_DUMP_V2 に対応している必要があります。MRT format は最近(ようやく) RFC 化されました。

I guess it was important because bgpd can manipulate AS4 (4 Bytes AS numbers)
but MRT TABLE_DUMP (version 1) can handle only 16 bits ASN. TABLE_DUMP_V2
include 32 bits ASN and full support for BGP Multiprocol extesions and was
defined in draft-ietf-grow-mrt-07.txt (MRT routing information export
format), sadly a Internet Draft and not a RFC.

The TABLE_DUMP_V2 Type updates the TABLE_DUMP Type to include 4-byte Autonomous System Number (ASN) support and full support for BGP multiprotocol extensions.

RouteViews でとっているデータがいつから TABLE_DUMP_V2 になったかは把握していないですが、たぶん 2008 年あたりでしょう。MRT データを扱うツールは結構あるのですが、最終更新が 2008 年以前になっている物は TABLE_DUMP_V2 には対応していない可能が高いので最近のデータを使う場合は注意が必要と思われます。例えば pybgpdump/0.2 (2007) は試してみましたが対応していないようでした。

bgpdump

準備

ダウンロード :

ここから落としてもいいけど bitbucket repository から最新のをもらってくるのが良いと思います。(Mercurial をつかいます。) あと、RouteViews のデータは bzip2 で圧縮してあるのですが、それをそのまま取り扱えるようにしてあるようなので bzip2 関連のパッケージが必要です。

$ aptitude install libbz2-dev

ソースの取得 :

~$ hg clone https://bitbucket.org/ripencc/bgpdump

コンパイル :

~$ cd bgpdump/
~/bgpdump$ ./bootstrap.sh
~/bgpdump$ ./configure
~/bgpdump$ make
~/bgpdump$ sudo make install
install -d /usr/local/bin /usr/local/include /usr/local/lib
install bgpdump /usr/local/bin
install bgpdump_attr.h bgpdump_formats.h bgpdump_lib.h bgpdump_mstream.h /usr/local/include
install libbgpdump.so libbgpdump.a /usr/local/lib
~/bgpdump$
~/bgpdump$ bgpdump
2012-01-15 20:26:01 [info] logging to syslog
bgpdump version 1.4.99.14
(略)
実行
~/bgpdump$ bgpdump -m ~/bgp-route-data/rib.20120310.1400.bz2 | head -n2
2012-03-10 23:17:58 [info] logging to syslog
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.4.0/22|2497 6453 7545 7545 7545 56203|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.4.0/22|7500 2516 6453 7545 7545 7545 56203|IGP|202.249.2.86|0|0||NAG||
~/bgpdump$

bgpparser

準備

ダウンロード :

これも、github リポジトリから最新版を落としてくるのが良いでしょう。

あと bgpparser は依存するライブラリ周りを準備するのが実は結構厄介です。以下のライブラリも併せてインストールします。

  • libxml2
  • log4cxx
  • boost >= 1.44

まずは bgpparser のソースをダウンロード

~/bgpparser$ git clone https://github.com/cawka/bgpparser.git

bgpparser のコンパイルとインストールはあと ./configure && make && make install という通常の流れ。ただその前にそのほかのライブラリをインストールしておく。

libxml2 のインストール

$ sudo aptitude install libxml2 libxml2-dev libxml2-utils

log4cxx のインストール

~$ aptitude install libapr1 libapr1-dev libaprutil1 libaprutil1-dev
~$ git clone https://cawka@github.com/cawka/log4cxx.git
~$ cd log4cxx/
~/log4cxx$ ./autogen.sh
~/log4cxx$ ./configure
~/log4cxx$ make
~/log4cxx$ sudo make install

つぎは boost のインストール。boost ver.1.44 以上が必要です。Ubuntu 11.10 だと普通に apt で boost をインストールすると 1.46 が入ってきますが、

~$ sudo aptitude install libboost-system-dev libboost-filesystem-dev libboost-regex-dev
~$ sudo aptitude install libboost-iostreams-dev libboost-test-dev

この状態で bgpparser で configure すると

checking for log4cxx... yes
checking for boostlib >= 1.44... yes
checking whether the Boost::System library is available... yes
checking for exit in -lboost_system-mt... yes
checking whether the Boost::Filesystem library is available... yes
checking for exit in -lboost_filesystem-mt... yes
checking whether the Boost::Program_Options library is available... yes
configure: error: Could not link against boost_filesystem-mt !

とかいわれるという。なのでソースからインストールし直してみた…。

ここでは 1.48.0 を使っています。

~$ tar xvzf boost_1_48_0.tar.gz
~/boost_1_48_0$ cd boost_1_48_0/
~/boost_1_48_0$ .//bootstrap.sh
~/boost_1_48_0$ ./b2
~/boost_1_48_0$ sudo ./b2 install

インストール先はデフォルトでは /usr/local/lib になる。ちなみに boost 最初に入れたときに bzip2 周りのヘッダファイルがなくて boost_iostreams がインストールされていなかったり、というのがあったので注意が必要…。

bgpparser をコンパイル & インストールします。

~/bgpparser$ ./configure --with-boost=/usr/local/ --with-boost-libdir=/usr/local/lib  CXXFLAGS=-O3 --enable-log4cxx
~/bgpparser$ make
~/bgpparser$ sudo make install

/usr/local/lib を LD_LIBRARY_PATH に通しておきます。

~$ export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
実行
~$ bgpparser2 --file ~/bgp-route-data/rib.20120310.1400.bz2 | head -n2
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.4.0/22|2497 6453 7545 7545 7545 56203|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.4.0/22|7500 2516 6453 7545 7545 7545 56203|IGP|202.249.2.86|0|0||NAG||
~$
ついで (mrt2xml)

MRT を XML に変換するツールも入っているのでそっちも作っておきます。(別途コンパイル&インストールしないと入らなかったので。)

~$ cd bgpparser/dumper/
~/bgpparser/dumper$ make
~/bgpparser/dumper$ sudo make install

実行(mrt2xml) :

~$ bgpparser -m ~/bgp-route-data/rib.20120310.1400.bz2 | head -n2
<BGP_MESSAGE version="0.2"><TIME><TIMESTAMP>1331388000</TIMESTAMP><DATETIME>2012-03-10T14:00:00Z</DATETIME></TIME><PEERING><SRC_ADDR afi="IPV4" afi_value="1">202.249.2.169</SRC_ADDR><SRC_PORT></SRC_PORT><SRC_AS>2497</SRC_AS><DST_ADDR afi="IPV4" afi_value="1">202.249.2.169</DST_ADDR><DST_PORT></DST_PORT><DST_AS>2497</DST_AS></PEERING><ASCII_MSG><MARKER length="16">FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</MARKER><LENGTH>23</LENGTH><TYPE>UPDATE</TYPE><UPDATE><WITHDRAWN_LEN>0</WITHDRAWN_LEN><WITHDRAWN count="0"/><PATH_ATTRIBUTES_LEN>41</PATH_ATTRIBUTES_LEN><PATH_ATTRIBUTES count="3"><ATTRIBUTE><FLAG><TRANSITIVE/></FLAG><LENGTH>1</LENGTH><TYPE value="1">ORIGIN</TYPE><ORIGIN value="0">IGP</ORIGIN></ATTRIBUTE><ATTRIBUTE><FLAG><TRANSITIVE/><EXTENDED/></FLAG><LENGTH>26</LENGTH><TYPE value="2">AS_PATH</TYPE><AS_PATH complete="2497 6453 7545 7545 7545 56203"><AS_SEG type="AS_SEQUENCE" length="6"><AS>2497</AS><AS>6453</AS><AS>7545</AS><AS>7545</AS><AS>7545</AS><AS>56203</AS></AS_SEG></AS_PATH></ATTRIBUTE><ATTRIBUTE><FLAG><TRANSITIVE/></FLAG><LENGTH>4</LENGTH><TYPE value="3">NEXT_HOP</TYPE><NEXT_HOP>202.249.2.169</NEXT_HOP></ATTRIBUTE></PATH_ATTRIBUTES><NLRI count="1"><PREFIX>1.0.4.0/22</PREFIX></NLRI></UPDATE></ASCII_MSG></BGP_MESSAGE>
<BGP_MESSAGE version="0.2"><TIME><TIMESTAMP>1331388000</TIMESTAMP><DATETIME>2012-03-10T14:00:00Z</DATETIME></TIME><PEERING><SRC_ADDR afi="IPV4" afi_value="1">202.249.2.86</SRC_ADDR><SRC_PORT></SRC_PORT><SRC_AS>7500</SRC_AS><DST_ADDR afi="IPV4" afi_value="1">202.249.2.86</DST_ADDR><DST_PORT></DST_PORT><DST_AS>7500</DST_AS></PEERING><ASCII_MSG><MARKER length="16">FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</MARKER><LENGTH>23</LENGTH><TYPE>UPDATE</TYPE><UPDATE><WITHDRAWN_LEN>0</WITHDRAWN_LEN><WITHDRAWN count="0"/><PATH_ATTRIBUTES_LEN>45</PATH_ATTRIBUTES_LEN><PATH_ATTRIBUTES count="3"><ATTRIBUTE><FLAG><TRANSITIVE/></FLAG><LENGTH>1</LENGTH><TYPE value="1">ORIGIN</TYPE><ORIGIN value="0">IGP</ORIGIN></ATTRIBUTE><ATTRIBUTE><FLAG><TRANSITIVE/><EXTENDED/></FLAG><LENGTH>30</LENGTH><TYPE value="2">AS_PATH</TYPE><AS_PATH complete="7500 2516 6453 7545 7545 7545 56203"><AS_SEG type="AS_SEQUENCE" length="7"><AS>7500</AS><AS>2516</AS><AS>6453</AS><AS>7545</AS><AS>7545</AS><AS>7545</AS><AS>56203</AS></AS_SEG></AS_PATH></ATTRIBUTE><ATTRIBUTE><FLAG><TRANSITIVE/></FLAG><LENGTH>4</LENGTH><TYPE value="3">NEXT_HOP</TYPE><NEXT_HOP>202.249.2.86</NEXT_HOP></ATTRIBUTE></PATH_ATTRIBUTES><NLRI count="1"><PREFIX>1.0.4.0/22</PREFIX></NLRI></UPDATE></ASCII_MSG></BGP_MESSAGE>
~$

XML については Internet-Draft が出ているようですが今回は動くのを確認しただけです。

MRT 形式データのダンプツール比較
  • bgpdump -m
~$ bgpdump -m ~/bgp-route-data/rib.20120310.1400.bz2 | head -n5
2012-03-11 00:44:41 [info] logging to syslog
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.4.0/22|2497 6453 7545 7545 7545 56203|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.4.0/22|7500 2516 6453 7545 7545 7545 56203|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.16.0/22|2497 2519|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.16.0/22|7500 2519|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.16.0/23|2497 2519|IGP|202.249.2.169|0|0||NAG||
~$
  • bgpparser2
~$ bgpparser2 ~/bgp-route-data/rib.20120310.1400.bz2 | head -n5
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.4.0/22|2497 6453 7545 7545 7545 56203|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.4.0/22|7500 2516 6453 7545 7545 7545 56203|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.16.0/22|2497 2519|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.86|7500|1.0.16.0/22|7500 2519|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP2|1331388000|B|202.249.2.169|2497|1.0.16.0/23|2497 2519|IGP|202.249.2.169|0|0||NAG||
~$
  • bgpparser -B
~$ bgpparser -B ~/bgp-route-data/rib.20120310.1400.bz2 | head -n5
TABLE_DUMP|1331388000|B|202.249.2.169|2497|1.0.4.0/22|2497 6453 7545 7545 7545 56203|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP|1331388000|B|202.249.2.86|7500|1.0.4.0/22|7500 2516 6453 7545 7545 7545 56203|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP|1331388000|B|202.249.2.169|2497|1.0.16.0/22|2497 2519|IGP|202.249.2.169|0|0||NAG||
TABLE_DUMP|1331388000|B|202.249.2.86|7500|1.0.16.0/22|7500 2519|IGP|202.249.2.86|0|0||NAG||
TABLE_DUMP|1331388000|B|202.249.2.169|2497|1.0.16.0/23|2497 2519|IGP|202.249.2.169|0|0||NAG||
~$

……bgpparser の -B オプションは "output bgpdump compatible ascii short format," ってことになってるんだけど、テーブルタイプが合わないのは何なんだろうね。バグ?

経路情報の投入

準備

bgpsimple で、テキストに変換したMRTデータを実際にルータへ注入します。

bgpsimple は perl ベースのツールです。cpan で Net::BGP をインストールしておく必要があります。

データは "one-line per entry with unix timestamps" で作っておきます。

~/bgpsimple$ bgpdump -m ~/bgp-route-data/rib.20120310.1400.bz2 > myroutes
2012-03-11 00:23:17 [info] logging to syslog
~/bgpsimple$

実行。引数指定が面倒なのでスクリプトでやるのが楽でしょう。

~/bgpsimple$ cat bgptest.sh
#!/bin/sh

MYAS=64604
MYIP=172.16.11.16
PEERIP=172.16.11.1
PEERAS=64601
HOLD=600
KALIVE=60
BGPSIMPLE="./bgp_simple.pl -myas $MYAS -myip=$MYIP -peerip=$PEERIP -peeras=$PEERAS -holdtime=$HOLD -keepalive=$KALIVE"
$BGPSIMPLE -p myroutes -v
実行
~/bgpsimple$ sudo ./bgptest.sh
---------------------------------------- CONFIG SUMMARY --------------------------------------------------
Configured for an eBGP session between me (ASN64604, 172.16.11.16) and peer (ASN64601, 172.16.11.1).
Using 60 seconds as KeepAlive value and 600 seconds as HoldTime value for this peer.
Generating verbose output, level 1.
Will use prefixes from file myroutes.
Will set next hop address to 172.16.11.16 because of eBGP peering.
----------------------------------------------------------------------------------------------------------
(略)
Update received from peer [172.16.11.1], ASN [64601]: prfx [223.255.229.0/24] aspath [64601 64604 7500 7660 9304 9326 45727] nxthp [172.16.11.1] comm [] orig [IGP] agg []
Update received from peer [172.16.11.1], ASN [64601]: prfx [223.255.230.0/24] aspath [64601 64604 7500 7660 4635 9498 45727] nxthp [172.16.11.1] comm [] orig [IGP] agg []
Update received from peer [172.16.11.1], ASN [64601]: prfx [223.255.240.0/24 223.255.240.0/22 223.255.241.0/24 223.255.242.0/24 223.255.243.0/24] aspath [64601 64604 7500 2516 10026 55649] nxthp [172.16.11.1] comm [] orig [IGP] agg []

フルルート(39万経路弱) いれるとデフォルトの設定 (Keepalive:60s, Holdtime:180s) だと peer 切れてしまったので、Holdtime は長めにとってあります。

ちなみに、Cisco 1812J メモリ 256MB はフルルート注入には耐えられませんでした。"%BGP-5-ADJCHANGE: neighbor 172.16.11.16 Down No memory" とか出て落ちる。384MB(128+256) だと何とかなるけど CLI のレスポンスとか重め。650MB (128+512) あれば大丈夫だね。

*1:メジャーな Linuxディストリビューションで公式のパッケージで残っているのはこれが最後だったのではなかろうか?