# gobgpdのクライアントとしてはCIであるgobgpコマンドだけで結構な用途をカバーできたりすると自分では思ってたりします。-jオプションとかも活用すべし。(json出力だとコミュニティが生値らしいけど。)
最新(2.x系)gobgpd でpythonでクライアントを書いて動かそうとした話:gobgpコマンドもgrpcでサービスプロセスとインタフェースをとっており、やろうとしてることは、pythonのgrpcを調整して、提供されている*.protoインタフェースを理解する、に帰着する。
gRPC Python Instrationに従ってpipでgrpcio, grpcio-toolsをインストールすると、grpcio-toolsのときにprotobuf-3.9.1も一緒に入ってきます。
今日日時点(2019/8/24)にpipでインストールする grpcio-toolsで*.protoから作成する*_pb2.py *_pb2_grpc.pyがgoogle.protobufと何かコード仕様面で同期がとれていないように見えました。
具体的には、any.proto,empty.protoをimportしている*.protoからできる*_pb2.pyの 記述がかみ合っていない感じ。今、例えば、gobgp.protoをpython -m grpc_tools.protocすると、注目する部分範囲が以下のように出力されます。
from Any import any_pb2 as any_dot_any__pb2 from Empty import empty_pb2 as empty_dot_empty__pb2 from Timestamp import timestamp_pb2 as timestamp_dot_timestamp__pb2
以前だと、このように出力されてました。
from google.protobuf import any_pb2 as any_dot_any__pb2 from google.protobuf import empty_pb2 as empty_dot_empty__pb2 from google.protobuf import timestamp_pb2 as timestamp_dot_timestamp__pb2
1)試しにAny/Empty/Timestampをgoogle.protobufと書き換えると、importは通るが
gobgpapi.Path.pattrs: "google.protobuf.Any" seems to be defined in "google/protobuf/any.proto", which is not imported by "gobgp.proto". To use it here, please add the necessary import. ... ...
のようにでる
2)*_pb2.py の書き換えを維持したままで、google.protobufをgitからcloneしてきたものに置き換えると、コードは動き出した。書き換えなしでは、Anyが見つからない、とかのようにでる。
こんな感じで、gobgpdリポジトリにあるサンプルのadd_path.pyも今日時点では、自己責任ワークアラウンドしないと動いてくれません。*1ちょっとしばらくgoogle.protobufのアップデート期待してます。
暇つぶしのお遊び
インターネットにつないだサーバでは常にsshでちょっかいかけてくるIP日常で、/var/log/auth.logをtail -fして'authentication failure'でgrepするとかでリアルタイムでみれます。
gobgpdを、複数(でなくても全然いいけど)ノードで起動しておいて、例示のadd_path.pyを流用して前述のダメなIP放り込んでいくということをにしてました。
- ダメなIPをprefix/prefix_len=32
- next hopは0.0.0.0にしておく→ 誰が(どのノードが)放り込んだかが分かる
- AS_PATHにはIPから変換したasn*2
コミュニティとかつけても、別にこれ以上つけて遊ぶ情報量がない。。
二台(某東ヨーロッパvps x 2)でgobgpd peerしてダメなIP収集動かしてみました。
ほんの数分でこの様です。。。*3
anonymous@vm214222:$ gobgp global rib Network Next Hop AS_PATH Age Attrs *> 37.59.110.165/32 212.24.99.177 16276 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 45.55.158.8/32 212.24.99.177 14061 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 45.226.111.12/32 212.24.99.177 266993 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 49.88.112.77/32 212.24.99.177 4134 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 89.36.215.248/32 212.24.99.177 199653 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 91.106.193.72/32 212.24.99.177 42695 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 91.218.64.92/32 0.0.0.0 44066 00:01:13 [{Origin: ?}] *> 92.222.88.30/32 212.24.99.177 16276 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 103.249.193.45/32 212.24.99.177 134764 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 106.12.36.98/32 212.24.99.177 38365 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 106.13.19.75/32 212.24.99.177 38365 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 118.174.45.29/32 212.24.99.177 131293 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 123.206.132.170/32 0.0.0.0 45090 00:00:18 [{Origin: ?}] *> 124.149.253.83/32 212.24.99.177 4739 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 125.212.203.113/32 212.24.99.177 38731 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 128.201.232.88/32 212.24.99.177 265934 00:00:50 [{Origin: ?} {LocalPref: 100}] *> 139.99.221.61/32 212.24.99.177 16276 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 139.155.19.146/32 212.24.99.177 45090 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 159.203.139.128/32 212.24.99.177 14061 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 192.241.201.182/32 212.24.99.177 14061 00:02:23 [{Origin: ?} {LocalPref: 100}] *> 218.92.0.132/32 0.0.0.0 4134 00:00:03 [{Origin: ?}] *> 222.240.1.0/32 0.0.0.0 4134 00:01:08 [{Origin: ?}]
よろしくない動作
しばらくしたら、片方でglobal rib見ようとしたら、こんなのが。IPv6からのfailureが契機みたいだったです。
まあ自分が不完全なことしただけで、gobgpdはIPv4だけでうごかしてるのに、AddPathRequestの呼び方が雑すぎた*4といえばそれまでです。
エラー吐いているのはクライアントのほうなので、サービスプロセスのルーティングテーブルに変な値登録してしまったってことですかね。
anonymous@vm214222:$ gobgp global rib panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x9c3c2e] goroutine 1 [running]: main.showNeighborRib(0xc15128, 0x6, 0x0, 0x0, 0x14047b8, 0x0, 0x0, 0xc00003a088, 0xce45e0) /home/fujita/git/gobgp/cmd/gobgp/neighbor.go:933 +0x87e main.showGlobalRib(0x14047b8, 0x0, 0x0, 0x0, 0xc00000e188) /home/fujita/git/gobgp/cmd/gobgp/global.go:1339 +0x5c main.newGlobalCmd.func2(0xc0000b18c0, 0x14047b8, 0x0, 0x0) /home/fujita/git/gobgp/cmd/gobgp/global.go:1621 +0x3f github.com/spf13/cobra.(*Command).execute(0xc0000b18c0, 0x14047b8, 0x0, 0x0, 0xc0000b18c0, 0x14047b8) /home/fujita/go/pkg/mod/github.com/spf13/cobra@v0.0.0-20170731170427-b26b538f6930/command.go:653 +0x2af github.com/spf13/cobra.(*Command).ExecuteC(0xc0000b1440, 0xc00017a900, 0xc00017ab40, 0xc00017b200) /home/fujita/go/pkg/mod/github.com/spf13/cobra@v0.0.0-20170731170427-b26b538f6930/command.go:728 +0x2cc github.com/spf13/cobra.(*Command).Execute(0xc0000b1440, 0xc00014bf88, 0xc00014bf88) /home/fujita/go/pkg/mod/github.com/spf13/cobra@v0.0.0-20170731170427-b26b538f6930/command.go:687 +0x2b main.main() /home/fujita/git/gobgp/cmd/gobgp/main.go:32 +0x63