Zum Inhalt springen
labkompass

Logbuch#netzwerk#monitoring#control-center#docker

NetFlow v9: ohne Template ist jedes Paket unlesbar

Von Niclas Hennrich


MessungAusprobiert

Real gemessen — die Werte stehen im Eintrag. Gehört zum Vorhaben Homelab Control Center.

verlustfrei dekodiert
4500Flows/s
RAM des Collectors
18.8MiB
Verlust bei 14 200 Flows/s
0.05%

Warum überhaupt: Mein Dashboard kann Verkehr bisher nur je Leitung zeigen, nicht je Gerät. Dafür braucht es NetFlow — der Router exportiert dabei Datensätze über die Verbindungen, die durch ihn laufen. Bevor ich das in die Anwendung einbaue, wollte ich wissen, ob der Collector trägt und was er kostet.

Der Router konnte in dieser Phase noch gar nicht mitspielen. Der NetFlow-Export war nicht eingeschaltet und ließ sich auch nicht einschalten: Die Konfiguration geht nur über die Web-Oberfläche, der lesende Monitoring-Benutzer bekommt auf den passenden API-Endpunkt ein HTTP 403.

Also ein eigener Generator statt eines Mocks. Ein kleines Python-Skript, nur Standardbibliothek, das echte NetFlow-v9-Pakete baut — inklusive Template-FlowSets, 4-Byte-Padding und Sequenznummern — und sie über UDP schickt. Was beim Collector ankam, hatte damit denselben Weg genommen wie die Pakete eines echten Routers. Das war die beste Entscheidung des ganzen Versuchs, und zwar aus einem Grund, den ich vorher nicht kannte.

Der allererste Lauf sah nach Paketverlust aus. 200 Flows im Burst, rund 72 000 Flows/s — zurück kamen 179, dazu eine Warnung template error.

Das ist kein Verlust, sondern der Protokollvertrag. NetFlow v9 beschreibt den Aufbau seiner Datensätze in separaten Template-Records. Bis das erste Template angekommen und verarbeitet ist, sind alle Datensätze unlesbar — goflow2 verwirft sie, statt zu raten. Richtig so. Der gezielte Gegentest bestätigte es sauber: drei Pakete ohne jedes Template ergaben 0 dekodierte Flows und 3 Template-Fehler, deterministisch. Mit vorangehendem Template kamen 500 von 500 an.

Das heißt auch: Nach jedem Neustart fehlen Daten, auf beiden Seiten. Startet der Collector neu, ist alles unlesbar, bis der Router das nächste Template schickt — und andersherum genauso. Eine Oberfläche muss diese Lücke später als Lücke zeigen und nicht als Ruhe.

Die Lastreihe — drei Stufen à 20 Sekunden, 10 Flows je Paket, alle 20 Pakete ein Template:

Pakete/sFlows/sgesendetdekodiertverlorenCPU maxRAM
100~97019 46019 460015 %18,8 MiB
500~4 50089 93089 930061 %18,5 MiB
2 000~14 200284 470284 321149 (0,05 %)191 %23,3 MiB

Gemessen auf meinem Homeserver (Sechskern-i5, 16 GB RAM, Debian 13) gegen goflow2 v2.2.6 im Container. Der Lastgenerator lief auf demselben Rechner — die CPU-Werte enthalten seine Konkurrenz und sind eher zu hoch als zu niedrig. Der Speicherbedarf bleibt über alle Stufen bei rund 20 MiB. IPv4 und IPv6 werden beide dekodiert, ebenso TCP, UDP und ICMP.

Die Sorge war unbegründet. 20 MiB RAM und 15 % eines Kerns bei tausend Flows pro Sekunde — dass ein Collector den Homeserver belasten könnte, war schlicht falsch gedacht. Der Engpass wird woanders liegen, vermutlich beim Schreiben in die Datenbank. Und tatsächlich saßen die nächsten beiden Fehler genau dort — wenn auch andere, als ich erwartet hatte.

Was noch nicht bewiesen ist: dass die Kette mit dem echten Router läuft. Wie viele Flows dieses Heimnetz tatsächlich erzeugt, weiß ich nicht — das zeigt sich erst mit dem echten Export.

Kleinigkeit mit Folgen: goflow2 meldet für ICMP den Port 0. Mein Datenmodell verlangt dort „kein Wert" — eine 0 wäre ein gültiger Port und damit eine Behauptung. Solche Umrechnungen gehören an genau eine Stelle, sonst sickern sie als plausible Nullen in die Statistik.

Der Container wurde nach der Messung wieder entfernt; am Router habe ich nichts geändert.