sFlow は面倒くさいが、fluent-plugin-sflow を再実装する話
背景
ネットワークデバイスからの xFlow を Fluentd で集めて分析、あるいは可視化するということをよくやります。
ルーター製品であれば fluent-plugin-netflow が使えますが、スイッチ製品はそもそも NetFlow がサポートされていません。代わりに sFlow に対応のデバイスが多いものの、現実的に動く fluent-plugin がありません。
NetFlow に比べて sFlow 実装が面倒なためですが、取り組んでみると まあまあ収まりのいい形で実装できた気がする、という記事です。
sFlow の面倒くさい点
パケットデコーダーを内包しないといけない
sFlow は L2 情報が中心で、 L3 + ルーティングの情報は普通ありません。 Ethernet ペイロードの先頭 N バイトをコレクター側でデコードしないといけません。さらに、場合によっては下のような情報を付加してやる必要があります。
- Prefix Length
- SRC / DST AS 番号
- Protocol Nexthop
- 論理 ifIndex
パフォーマンス
sFlow は IP フローを意識していません。 NetFlow ではうまく Aggregate して Export パケットを減らしたりできますが、 sFlow では Export パケットが増えがちです。
デコードしないといけないわ pps 多いわで、 NetFlow よりパフォーマンスが問題になりやすいです。
sFlow と NetFlow の名寄せ
これは sFlow の問題ではありませんが、 sFlow と NetFlow を同じ基盤で扱うときに面倒な点です。
同じ情報でも、 sFlow の流儀と NetFlow の流儀はちがいます。たとえば、パケットが入ってくるインターフェイスの ifIndex は、 sFlow v5 では input
、 NetFlow v9 では input_snmp
になっています。
コレクター実装を考えるとき、単純に名寄せすればいいかもしれません。が、「どっちに寄せれば…?」で悩みます。
DNS クエリーはもっと悩ましいです。
NetFlow では
{ "protocol": 17, # or 6 "l4_dst_port": 53 }
で Export されますが、 sFlow では
{ "protocol": 17, "udp_dst_port": 53 }
もしくは
{ "protocol": 6, "tcp_dst_port": 53 }
で出たりします。UDP とTCP で別キー。*1 面倒くさい!!
コレクターで UDP / TCP Port を結合して Port にするかどうかは…悩ましい。ネットワークオペレーターの事情に応じて record_transformer
プラグインなどで名寄せすればよかろうと思い、今回の実装では sFlow の流儀のまま Export することにしました。
もうひとつ悩ましい例は Export パケットの SRC IP アドレス。sFlow にも Netflow にも該当するフィールドはありません。*2
fluent-plugin-netflow ではそれをhost
として格納していますが、 sFlow ではhost
は使えません。 HTTP HOST ヘッダーを格納するフィールドとして規定されているためです。。。面倒くさい!
このような流儀の違いが山のようにあります。 filter プラグインで名寄せしつつ、、、でパフォーマンスが出せるか十分に検討していませんが、とりえあず sFlow 流儀に従いました。
既存 fluent-plugin-sflow の BinData 問題
これも sFlow 自体の問題ではありませんが、実は fluent-plugin-sflow という gem は既に存在します。今回はそれを再実装した という形なのですが、既存のものにはいくつか問題があります。
1 . は最新の BinData では動かないのが根本原因で、仕様上むずかしそう。 2. も BinData が原因です。 ちなみに、fluent-plugin-netflow も当初は BinData ベースでしたが、パフォーマンスのために 低レベルなビット演算に変わったという経緯があります。*3
実装について
InMon 謹製の sflowtool に手を加え、 C 拡張として内包することにしました。
- 公式のパケットデコーダーを使える
- 頻度高くないが、まだメンテされているように見える
- パフォーマンス改善が見込める
- BinData とさよならできる
のがポイント。実装は こちら 。
ベンチマーク
手元の Macbook Pro Mid 2015 に 外から sFlow v5 を Export しました。
records / sec | |
---|---|
再実装版 | 14202 |
オリジナル版 | 220 |
まあまあ実用には耐えそう。
TODO
- テストを足す
- sflowtool にパッチしたとはいえ、バグを埋めているかもしれない
- 「動かないよ」という方がいらっしゃれば、ぜひ .pcap ください 🙇
- fluent-plugin-sflow メンテナー様にコンタクトしてみる
- 別実装なので…別 gem にするべきか、プルリクしてもいいものか思案中 💦
- 出力フォーマットが変わる → プルリクするならば互換性を壊す
- BGP の情報をインポートする