NetFlowは、ネットワークトラフィックを考慮して
シスコシステムズが作成したネットワークプロトコルです。 このプロトコルの最も一般的なバージョンは5と9です。9
番目のバージョンは、送信されるデータに応じてテンプレートが使用されるため、より柔軟です。
5番目のバージョンでは、仕様に従ってデータが送信されます。
NetFlowプロトコルトラフィック情報収集システムは、次のコンポーネントで構成されています。
- センサー デバイスを通過するトラフィックの統計を収集するデバイス(ルーター、L3スイッチ)。
- コレクター 。 センサーからデータを収集し、ストレージに入れます。
- アナライザー 。 コレクターが収集したデータを分析し、レポートを生成します。
C#のアナライザー機能の一部の開発、具体的には
NetFlowパッケージの分析について説明します
MikroTikルーターがセンサーとして使用されました。
ether1インターフェイスの
NetFlowを
オンにします。
/ip traffic-flow set enabled=yes interfaces=ether1
そして、コレクターを追加します(原則として、コレクターはポート2055、9555または9995でリッスンします):
/ip traffic-flow target add disabled=no version=9 address=192.168.0.100:9995
または同じことですが、
WinBoxを介して:

これで、
UDPポート
9995で
192.168.0.100の IPアドレスを持つコンピューターでは、バージョン
9のNetFlowパケットが
UDP (または
SCTP )に到着します。 パッケージには、動作するものがあります。
着信パケットを解析する
プロトコル仕様を検討し
た結果、各
NetFlowパケット(Nバイト)が以下で構成されていることがわかります。
- パケットヘッダー (20バイト)-フィールドを含む単一のコピーのパケットヘッダー:
- バージョン番号 ( UInt16-2バイト) -NetFlowバージョン番号。常に9です。
- カウント ( UInt16-2バイト)-レコードの総数。 さらに、この分野の記事は冒険でした。
- sysUpTime (UInt32-4バイト)-デバイスの開始からのミリ秒単位の時間-UpTime。
- UNIX秒 ( UInt32-4バイト)-パケットが送信された0000 UTC 1970からの秒数。
- シーケンス番号 ( UInt32-4バイト)-送信されたパケットのカウンター。パケットごとに常に増加しているため、それらの間のパケットが失われたかどうかを確認できます。
- ソースID ( UInt32-4バイト)-データストリーム番号。実際には、センサー側から複数のデータストリームを送信できます。
- FlowSet (N-20バイト)-テンプレート、データ... FlowSetは複数または1つにすることができます。 各FlowSetには、送信されるデータのタイプ(テンプレート、データ)から変更されていない2つのフィールドがあります。
- FlowSet ID ( UInt16 2バイト)-テンプレートの場合は常に0、オプションのテンプレートの場合は1、データの場合はテンプレートIDと等しいため、255を超える(256〜65535)。
- 長さ ( UInt16 2バイト) -FlowSet全体のサイズとFlowSet IDおよびLengthフィールド。
- 転送されるデータのタイプに応じたその他のフィールド。
テンプレートを含む
FlowSet IDを見て、
FlowSet IDフィールドで始まり、次に
Length 、次に:
- テンプレートID ( UInt16 2バイト)-データが送信される各テンプレートの一意のID。 256から65535の数;
- フィールド数 ( UInt16 2バイト)-テンプレート内のフィールドの数。 次に、フィールドタイプ( Field Type )とサイズ( Field Length )があります。
- フィールドタイプ ( UInt16 2バイト)- フィールドのタイプを指定する数値。 すべてのタイプはプロトコル仕様にあります;
- フィールドの長さ -バイト単位のフィールドの長さ。
データを含む
FlowSet IDを見て、
FlowSet IDフィールドで始まり、次に
Length 、次に:
- データ...フィールドとそのサイズに対応するデータ。
- パディング -4バイトの境界までゼロを埋めます。
いわゆるオプションのテンプレートとデータもあります。 私はそれらを考慮しません、彼らは私に会っていません、この理由で実装にライブラリがありませんが、すべてを追加することができます。
UMLクラス図をコンパイルしました(
NClassを使用):

または
pdfでそして、彼は入ってくるパケットを解析するライブラリを書きました。
すべてが開始するメインクラスは
Packetです。 その唯一のコンストラクタは、バイト単位の受信NetFlowパッケージと、現在の
テンプレートのリストである
Templatesクラスのオブジェクトを受け入れます。
次に、
Parse関数が
Packetsクラスのコンストラクターで呼び出され、
Templatesクラスのオブジェクトを受け取ります。
この関数は、パケットをヘッダー(20バイト)に分割し、
Headerクラスを介してさらに処理します。 対応する
FlowSetクラスへの処理のための
FlowSetの各
FlowSetの転送。
いくつかの
FlowSetが存在する可能性があるため、パケットの2番目の部分(ヘッダーの20バイトなし)を分析し、異なる
Flowsetに分割する
必要があります。
MikroTikの
パッケージ内の単一コピーにある
FlowSetが、
C#で
Netflow Simulatorを使用すると、パッケージ内に複数の
FlowSetがあるパッケージで作業できることが
注目に値します。 さらに、彼のおかげで、
MikroTikの
NetFlow v9の実装で面白いバグが見つかりました。詳細については、
こちらを
ご覧ください 。
C#のNetflow Simulator :
FlowSet`sのパッケージの一部を壊すコードスニペットを
次に示します。
this._flowset = new List<FlowSet>(); Int32 length = _bytes.Length - 20; Byte[] flowset = new Byte[length]; Array.Copy(_bytes, 20, flowset, 0, length); byte[] reverse = flowset.Reverse().ToArray(); int templengh = 0; while ((templengh + 2) < flowset.Length) { UInt16 lengths = BitConverter.ToUInt16(reverse, flowset.Length - sizeof(Int16) - (templengh+2)); Byte[] bflowsets = new Byte[lengths]; Array.Copy(flowset, templengh, bflowsets, 0, lengths); FlowSet flowsets = new FlowSet(bflowsets, templates); this._flowset.Add(flowsets); templengh += lengths; }
Headerクラスでは、パッケージ
ヘッダーがフィールドに解析されます。 これを行う前に、ヘッダーが逆になります。
this._bytes.Reverse().ToArray();
次に、ビットをフィールドのタイプ(たとえば、バージョンフィールド)に変換します。
this._version = BitConverter.ToUInt16(reverse, this._bytes.Length - sizeof(Int16) - 0);
はい、
ヘッダーフィールド
sysUpTimeのタイプは
TimeSpan です。このタイプに変換できます。
get { return new TimeSpan((long)this._uptime * 10000); }
UNIX Secsフィールドのタイプは
DateTimeです。
get { return new DateTime(1970, 1, 1).AddSeconds(this._secs); }
FlowSetの処理に
移りましょう。
FlowSet IDおよび
Lengthフィールドを受け取った後、残りのフィールドは
FlowSet IDに応じて解析され
ます 。 0または1の場合、これはパターンであり、256から65535の数値の場合、これはデータです。
これがテンプレートの場合、その処理を
Templateクラスに渡し、同じ
IDを持つテンプレートの存在をテンプレートストア(
Templatesクラスのオブジェクト)で確認して置き換えます。そうでない場合は、テンプレートを追加します。
このデータの場合、ストレージ(
Templatesクラスのオブジェクト)にそのようなテンプレート(
FlowSet ID ==
Template ID )が存在するかどうかを確認し、存在する場合は、このテンプレートを
DeepClone関数でコピーし、
フィールド-Fieldに入力します。そうでない場合は、テンプレートがないため何もしませんバイトのセット。
DeepClone関数:
public static object DeepClone(object obj) { object objResult = null; using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); ms.Position = 0; objResult = bf.Deserialize(ms); } return objResult; }
フィールドはフィールドであり、次のパラメーターがあります。
また、リポジトリ内の
テンプレートの フィールドには、
値パラメータがありません。
値は空ですが、
FlowSetで
テンプレートパッケージを処理する場合、
Packetオブジェクトには既に
Valueフィールドが含まれています。
これに加えて、
FieldType列挙もあります-型名がこの型の番号に対応する列挙です。 (
フィールドの 型パラメーター)
このライブラリが機能するための例が作成されました。
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetFlow; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace Consoles { class Program { static void Main(string[] args) { Templates _templates = new Templates(); Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9995); sock.Bind(iep); EndPoint ep = (EndPoint)iep; byte[] data = new byte[2048]; while (true) { int recv = sock.ReceiveFrom(data, ref ep); Console.ReadKey(); Console.Clear(); byte[] bytes = new byte[recv]; for (int i = 0; i < recv; i++) bytes[i] = data[i]; Packet packet = new Packet(bytes, _templates); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(packet.ToString()); } sock.Close(); Console.ReadKey(); } } }
ソケットを作成し、PCのUDP 9995ポートでリッスンします。
_templatesはテンプレートリポジトリです。 到着した各パケットを
Packetクラスの
パケットオブジェクトに送り、テンプレートストレージも渡します。 次に、
packet.ToString()を実行し
ますこのオーバーロードされた関数は、パケットの内容を表示し、すべてが正常に機能することを確認するためにのみ必要です。
ライブラリはこれですべてです
。NetFlowプロトコルを使用してTraffic Analyzerをさらに記述するために使用できるようになりました。
MikroTikの例:
リポジトリにテンプレートのないパッケージを取得しました:

センサーからテンプレートを取得しました:

リポジトリにテンプレートがあるデータを取得しました:

MikroTikの NetFlow v9の実装エラー
このトピックを分析する過程で、
MikroTikの
NetFlow v9の実装でエラーが見つかりました。 エラーの本質:
パケットヘッダー(
パケットヘッダー )の
カウントフィールドには以下が含まれます。
カウント
エクスポートパケット内のレコードの総数。
オプションFlowSetレコード、テンプレートFlowSetレコード、および
データFlowSetレコード。
つまり すべての
FlowSetのすべてのレコードと
MikroTikのすべてのレコードが含まれます。このフィールドは、複数のテンプレートまたはデータが転送される場合でも、常に1に等しくなります(上記のスクリーンショットを参照)。 つまり
MikroTikのロジックによると、
Countフィールドは
FlowSetsの数(レターで私に書いたもので、スクリーンショットから見ることができます)であり、仕様にあるように、すべてのテンプレートとデータの総数に等しくなければなりません。 このため、パケット解析で
Countフィールドを使用するのは困難です。
C#のNetflow Simulatorの例を次に示し
ます (
Ciscoからもデータを受信したいのですが、そのような機会はありません。読者の1人がこれをチェックするかもしれません)。
リポジトリにテンプレートのないパッケージを受け取りました(
Countに注意してください):

センサーからテンプレートを取得しました(同時に2つの
FlowSetsがありますが、
MikroTikが発生しないこと
が判明しました。
カウントに注意してください。テンプレートは7 = 1、データレコードは6です
。MikroTikのロジックによると、
Countは2 = 2
FlowSet `a):

リポジトリにテンプレートがあるデータを取得しました(
Countに注意してください):

繰り返しますが、
Wiresharkのパケットフィールド
カウントはマークされています:

繰り返しますが、
Cisco Wiresharkのomで画面を送信するすべての人に非常に感謝します。 ここに入れます。
ソースコードは
こちらから入手でき
ます 。
作成がガイドされたとき:
ウィキペディアの資料:NetflowCaligare:NETFLOWとは?プロトコル仕様バージョン9今日(19:05 07/30/2013)
MikroTikは答えました:
MikroTikサポート[Dzintars] support@mikrotik.comこんにちは
問題を報告していただきありがとうございます(記事の著者が正しく指摘しました
netflowパケットヘッダーのカウント値が常に正しく設定されているとは限りません)。 の
この問題は、RouterOSの次のバージョンで修正される予定です。
よろしく、
ジンター
UPD: RouterOS 6.2では、このバグは修正されました。
今日(13:22 09/13/2013)
MikroTikの書き込み:
MikroTikサポート[Dzintars] support@mikrotik.comこんにちは
NetFlow V9カウントフィールドの問題はバージョン6.2で修正されました
よろしく、
ジンター