CuteIP Updates 2:Akvorado を利用したフロー情報の取得

CuteIP Updates 2 では Akvorado を利用したフロー情報の取得を取り上げます。

CuteIP Updates 2 は、2023/01/21 に公開された CuteIP Updates 1 から 4 ヶ月ほど経過してしまいました。これまで、今回取り上げるフロー情報の取得以外にも監視基盤などを構築しました。それらについては今後の CuteIP Updates にて取り上げます。

さて、CuteIP では Akvorado を利用してフロー情報を取得する環境を構築しました。

環境

  • フローコレクタ:Akvorado v1.8.1
  • sFlow エージェント:hsflowd 2.0.49-1
  • Debian 11

Akvorado にした理由

フローコレクターの候補としては ElastiFlow と Akvorado がありました。簡単な要件としては、そこまでマシンリソースを消費しないものが望ましいと考えていました。このような要件においては ElastiFlow よりも Akvorado のほうが少ないリソース消費で動かせそうということで、Akvorado を選択しました。他には、私が Akvorado のほうに興味を持っていたからというのもあります。

Linux ルーターにおける sFlow エージェント “hsflowd”

AS63797 の対外接続用 BGP ルーターは Linux で構成されています。sFlow エージェントとして hsflowd を利用しています。現在は大量のトラフィックが流れていない状況ですが、hsflowd は特に問題なく動作しています。精度については、きちんと確認していないのでなんとも言えません。

Akvorado + Linux におけるネットワークインターフェース名取得

Akvorado と Linux で動く snmpd の組み合わせで動かすと、Akvorado にて認識されるネットワークインターフェース名がわかりにくくなってしまう問題に遭遇したので、それについて説明します。

Akvorado はフロー情報を送ってきたフローエージェント(エクスポーター)に対して SNMP Get してネットワークインターフェースに関する情報を取得します。

取得対象の OID: https://github.com/akvorado/akvorado/blob/v1.8.1/inlet/snmp/poller.go#L172-L174

各 OID において期待されるレスポンス: https://github.com/akvorado/akvorado/blob/v1.8.1/demoexporter/snmp/server.go#L38-L55

そのためフローエージェントが動いている Linux ルーターは、snmpd などで SNMP Get に応答しなければなりません。

libvirt で構築した Linux ルーターにて snmpd と hsflowd を稼動させた上で Akvorado にフロー情報を送信すると、Akvorado 側(表示時の Dimensions → InIfName などに該当)では一部ネットワークインターフェース名を「eth0」などではなく「Red Hat, Inc. Device 0001」と認識してしまいます。これは単純に snmpd が 1.3.6.1.2.1.2.2.1.2ifDescr で Red Hat, Inc. Device 0001 などと返してしまうからです。

ifDescr 1.3.6.1.2.1.2.2.1.2: https://oidref.com/1.3.6.1.2.1.2.2.1.2

例えば、snmpd が稼動しているホストに対して snmpwalk で取得すると次のような結果を取得できます。

$ snmpwalk -v 2c -On -c public localhost 1.3.6.1.2.1.2.2.1.2
.1.3.6.1.2.1.2.2.1.2.1 = STRING: "lo"
.1.3.6.1.2.1.2.2.1.2.2 = STRING: "Red Hat, Inc. Device 0001"
.1.3.6.1.2.1.2.2.1.2.3 = STRING: "Red Hat, Inc. Device 0001"
.1.3.6.1.2.1.2.2.1.2.4 = STRING: "docker0"
.1.3.6.1.2.1.2.2.1.2.285 = STRING: "br-f73df603e9ef"
.1.3.6.1.2.1.2.2.1.2.287 = STRING: "veth901ceed"
.1.3.6.1.2.1.2.2.1.2.291 = STRING: "veth33a534a"
.1.3.6.1.2.1.2.2.1.2.297 = STRING: "veth9d252b7"
.1.3.6.1.2.1.2.2.1.2.299 = STRING: "veth25789de"
.1.3.6.1.2.1.2.2.1.2.315 = STRING: "vethef89298"
.1.3.6.1.2.1.2.2.1.2.317 = STRING: "vethc544bb3"

snmpd において eth0 などの ip a コマンドなどで表示されるようなわかりやすい名前は 1.3.6.1.2.1.31.1.1.1.1ifName で取得できます。先ほどと同様に snmpwalk コマンドで取得すると次のような結果を取得できます。

ifName 1.3.6.1.2.1.31.1.1.1.1: https://oidref.com/1.3.6.1.2.1.31.1.1.1.1

$ snmpwalk -v 2c -On -c public localhost 1.3.6.1.2.1.31.1.1.1.1
.1.3.6.1.2.1.31.1.1.1.1.1 = STRING: "lo"
.1.3.6.1.2.1.31.1.1.1.1.2 = STRING: "eth0"
.1.3.6.1.2.1.31.1.1.1.1.3 = STRING: "mgmt1"
.1.3.6.1.2.1.31.1.1.1.1.4 = STRING: "docker0"
.1.3.6.1.2.1.31.1.1.1.1.285 = STRING: "br-f73df603e9ef"
.1.3.6.1.2.1.31.1.1.1.1.287 = STRING: "veth901ceed"
.1.3.6.1.2.1.31.1.1.1.1.291 = STRING: "veth33a534a"
.1.3.6.1.2.1.31.1.1.1.1.297 = STRING: "veth9d252b7"
.1.3.6.1.2.1.31.1.1.1.1.299 = STRING: "veth25789de"
.1.3.6.1.2.1.31.1.1.1.1.315 = STRING: "vethef89298"
.1.3.6.1.2.1.31.1.1.1.1.317 = STRING: "vethc544bb3"

eth0 などのわかりやすい名前が Akvorado で認識されてほしいです。そのため、ifDescr で eth0 のようなネットワークインターフェース名を返す簡易的な SNMP エージェントを作成しました。

https://github.com/cuteip/snmp-agent-akvorado

これは Go で書かれていて、Go のパッケージである https://github.com/slayercat/GoSNMPServer を利用したものです。Akvorado が SNMP Get してくる OID に対する応答を用意しておくという単純なものです。利用方法については README を参照してください。GitHub Issue にいくつか Issue がある通り、機能など細かいところはきちんと実装していません。

Akvorado と snmp-agent-akvorado を利用することで、Akvorado は eth0 のようなネットワークインターフェース名を認識するようになりました。

snmp-agent-akvorado を作成する前に他の解決手法も検討しましたが、実現できなかったり手間が大きかったりするためやめました。ネットワークインターフェースを管理している systemd-networkd の設定で ifDescr の値を変更できないかと調べてみたものの、それらしき項目は見つかりませんでした。また、Akvorado 側を fork して取得対象の OID を変更することも検討しましたが、fork による追従の手間などがあるためやめました。

Built with Hugo
テーマ StackJimmy によって設計されています。