naoki86star

インターネットの片隅でなにかしら書いてみる

gobgpd + grpc + python in Aug/2019

# 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

*1:あるいはgithubからgrpcを引っ張ってきてgrpc,google.protobufを入れるのを試すか

*2:いつものmaxminddbに感謝

*3:それぞれのノードでBANするような仕掛けいれてみるとか。。んーそれはそれでgobgpdのどこをいじるか

*4:ほぼsampleのまま