Es war 7:41 Uhr an einem Dienstag, als das Telefon klingelte. Die Buchhaltung könne seit Montagabend nicht mehr mit dem ERP arbeiten, „das System hängt einfach“. Im Monitoring fand ich nichts: CPU bei 20 Prozent, Speicher zur Hälfte frei, keine rote Ampel auf irgendeinem Dashboard. Die Anwendungslogs sahen sauber aus, der Datenbankserver meldete für jede Anfrage brav vier Millisekunden. Trotzdem rief alle zehn Minuten jemand an, und ich fing an, an meinen Messwerten zu zweifeln statt am Netz.
Um 9 Uhr hing ich mich auf dem Core-Switch in den Uplink zum Server-VLAN und ließ fünf Minuten mitlaufen. Zwei Minuten nach dem Öffnen der Datei in Wireshark war der Fall erledigt: Von 4.812 Datenpaketen in Richtung ERP waren 61 Pakete ein zweites Mal gesendet worden, und zwar alle aus derselben Quellgruppe. Der Verlust lag nicht auf dem Hinweg zum Server, sondern auf dem Rückweg, auf dem Uplink zwischen zwei Switches. Ein Port lief dort wegen eines Konfigurationsrests mit 100 Mbit und halbem Duplex, während der Nachbar-Port mit einem Gigabit lief. Kein Monitoring der Welt hätte das gemeldet, weil kein Gerät einen Fehlerzähler hochgezählt hat. Der Mitschnitt zeigte es in zwei Minuten.
Warum ein Mitschnitt mehr wert ist als zehn Vermutungen
Wenn zwei Leute über ein Netzproblem streiten, hat jeder eine Theorie und niemand Daten. Ist es die Firewall? Der Loadbalancer? Das neue Update? Ein Mitschnitt beendet diese Debatte, weil er die Frage nicht beantwortet, sondern die Fakten liefert: Welche Pakete sind wirklich über die Leitung gegangen, mit welcher Größe, mit welcher Zeitdifferenz und mit welchen Sequenznummern. Auf Kabeln lügt niemand. Ein Paketmitschnitt ist damit das einzige Werkzeug in der Admin-Werkzeugkiste, das Hersteller- und Abteilungsgrenzen einfach ignoriert.
Wichtig ist dabei die Erwartungshaltung. Ein Mitschnitt sagt dir selten „die Firewall ist schuld“. Er sagt dir, dass ein SYN rausgeht und kein SYN/ACK zurückkommt. Ob das an der Firewall, am Server oder an einer falschen Route liegt, entscheidest du dann mit diesem Fakt in der Hand. Genau so habe ich es oben gemacht: Der Mitschnitt zeigte Retransmits nur in eine Richtung, und das war der Hinweis auf einen Uplink und nicht auf den Server.
Capture-Filter und Display-Filter: zwei Welten, ein Klassiker-Fehler
Die häufigste Verwechslung in der Paketanalyse passiert ganz am Anfang. Es gibt zwei völlig unterschiedliche Filter-Sprachen, und sie arbeiten zu unterschiedlichen Zeitpunkten:
Capture-Filter werden von der Capture-Engine ausgewertet, bevor ein Paket in die Datei oder in den Arbeitsspeicher geschrieben wird. Die Syntax heißt BPF, „Berkeley Packet Filter“, und sie ist die Sprache, die auch tcpdump spricht. Was der Capture-Filter wegwirft, ist unwiderruflich weg — es landet nicht in der Datei und lässt sich später nicht zurückholen. Das ist sein Vorteil (die Datei bleibt klein, die CPU-Last niedrig) und sein Risiko.
Display-Filter sind Wireshark-Sprache. Sie wirken auf eine Datei, die schon existiert, und blenden nur aus, was du gerade nicht sehen willst. Die Pakete liegen weiterhin vor. Wenn du merkst, dass du falsch gefiltert hast, änderst du einfach den Ausdruck in der Filterzeile.
Der klassische Fehler: Du willst bei einer Analyse nur HTTP-Fehler sehen und wirfst im Capture-Filter alles außer Port 80 weg. Zwei Stunden später stellt sich heraus, dass genau die DNS-Auflösung das Problem war — nur ist DNS jetzt nicht in der Datei. Die Regel aus der Praxis lautet deshalb: Mit Capture-Filtern so grob wie möglich schneiden und so fein wie nötig. Ich filtere beim Mitschnitt fast immer nur nach Host oder Netz und schaue mir den Rest in Wireshark an.
Für Adressausdrücke lohnt es sich, das Netz vorher sauber zu kennen. Wenn du bei einem Ausdruck wie net 192.168.10.0/24 unsicher bist, ob die Maske stimmt, hilft der bitcalc Subnetz-Rechner: Netzadresse und CIDR kurz gegengeprüft, und der tcpdump-Audruck greift danach wirklich die Geräte, die du meinst.
tcpdump: fünf Schalter, die den Alltag abdecken
tcpdump ist auf jedem Server dabei, läuft über SSH und braucht keine Grafik. Für 90 Prozent der Fälle reichen fünf Optionen:
-iwählt die Schnittstelle,-i anynimmt alles mit. Ohne Angabe rät tcpdump und liegt gern falsch.-nnschaltet Namensauflösung für Hosts und Ports ab. Ohne das wartet tcpdump auf DNS-Antworten und verfälscht dir nebenbei die Zeiten.-wschreibt in eine Datei statt auf die Konsole. Das ist der eigentliche Profi-Modus, denn nur die Datei kannst du später in Wireshark öffnen.-rliest eine gespeicherte Datei wieder ein, ohne sie neu mitschneiden zu müssen.-cstoppt nach einer festen Paketanzahl, was bei Verdacht auf Schleifen Gold wert ist.
Ein typischer Aufruf für die oben beschriebene Lage auf einem Server sieht so aus:
$ sudo tcpdump -i eth0 -nn -s 0 -c 5000 \
'host 10.0.0.5 and port 443' -w /tmp/erp.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
5000 packets captured
5000 packets received by filter
0 packets dropped by kernel
Zwei Dinge an dieser Ausgabe solltest du immer lesen. Erstens 0 packets dropped by kernel. Steht dort eine Zahl größer null, hat der Kernel Pakete verworfen, weil tcpdump nicht schnell genug aus der Ringpuffer-Kopie gelesen hat. Dann ist deine Analyse auf Sand gebaut, denn dir fehlt am Ende genau das Paket, um das es geht. Zweitens die Snapshot-Länge. Ohne -s 0 schneidet tcpdump die Pakete nach 262144 Bytes ab — bei modernen MTUs unkritisch, bei Jumbo-Frames ein Problem, und bei manchen Analyse-Werkzeugen fehlen dann Nutzdaten.
Die Ausdruckssprache selbst ist kleiner, als sie aussieht. host 10.0.0.5 filtert beide Richtungen, src host und dst host trennen sie. net 192.168.10.0/24 fasst ein Netz zusammen, port 443 einen Dienst, und portrange 10000-10100 einen Bereich. Verknüpft wird mit and, or und not, wobei Klammern beim Aufruf in Anführungszeichen gehören, sonst interpretiert die Shell sie. Willst du gezielt Verbindungsaufbauten sehen, geht auch das im Capture-Filter:
$ sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
14:22:07.914213 IP 10.0.0.5.51234 > 10.0.0.80.443: Flags [S], seq 3847291055, win 64240
Das tcp-ack == 0 ist der entscheidende Teil: Es unterscheidet das reine SYN vom SYN/ACK, sonst siehst du beide und kannst sie nur an den Flags im Ausdruck auseinanderhalten.
Mitschneiden, ohne die Platte zu füllen
Ein Mitschnitt auf einem vielbefahrenen Uplink wächst schneller, als den meisten bewusst ist. Bei 600 Mbit Durchsatz und vollen Paketköpfen kommen schnell mehrere Gigabyte pro Minute zusammen. Deshalb schneidet man nie einfach ins Leere, sondern in einen Ringpuffer:
$ sudo tcpdump -i eth0 -nn -s 0 -w /var/tmp/cap-%Y%m%d-%H%M.pcap \
-G 300 -z gzip
Mit -G 300 rotiert die Ausgabedatei alle fünf Minuten, das Zeitformat im Dateinamen macht sie sortierbar, und -z gzip komprimiert die fertige Datei hinterher. So hast du immer die letzten Stunden griffbereit und sprengst trotzdem keine Partition. Das Gegenstück für vorhandene Dateien ist editcap aus dem Wireshark-Paket:
$ editcap -c 50000 gross.pcap klein.pcap # Datei in Häppchen von 50.000 Paketen teilen
$ editcap -i 60 gross.pcap minuten.pcap # eine neue Datei pro Minute
$ capinfos gross.pcap # Zeitraum, Paketanzahl, Dauer, Durchsatz
capinfos ist dabei der unterschätzte Held der Vorbereitung. Es sagt dir in einer Ausgabe, über welchen Zeitraum die Datei geht, wie viele Pakete drin sind und wie hoch der mittlere Durchsatz war. Erst damit weißt du, ob dein Mitschnitt die Störung überhaupt enthält oder ob du das Fenster um zwei Stunden verpasst hast. Vor jeder langen Analyse in Wireshark schaue ich mir erst capinfos an — das erspart erstaunlich viel Klickarbeit in der falschen Datei.
Wireshark: filtern statt scrollen
In Wireshark entscheidet nicht die Scroll-Geschwindigkeit, sondern die Filterzeile. Über allen anderen Filtern stehen für mich die Analyse-Felder, die Wireshark selbst berechnet, sobald eine TCP-Verbindung vollständig im Mitschnitt liegt:
tcp.analysis.retransmission # Paket wurde erneut gesendet
tcp.analysis.fast_retransmission # schneller Wiederholversuch nach Duplikat-ACKs
tcp.analysis.ack_rtt > 0.05 # RTT einzelner ACKs größer 50 ms
tcp.analysis.zero_window # Empfänger meldet vollen Puffer
tcp.options.mss_val < 1460 # ungewöhnlich kleine MSS im Handshake
http.response.code >= 400 # echte Fehlerantworten
icmp.type == 3 && icmp.code == 4 # Fragmentation needed
Diese Felder sind Schätzungen von Wireshark auf Basis der Paketreihenfolge und nicht die Wahrheit eines Servers. Genau das ist aber ihre Stärke: Sie finden Muster, die man mit bloßem Auge in 40.000 Zeilen nie sieht. Wenn du auf der Kommandozeile arbeitest, geht derselbe Display-Filter über tshark:
$ tshark -r erp.pcap -Y 'tcp.analysis.retransmission' -T fields \
-e frame.time_relative -e ip.src -e ip.dst -e tcp.seq
-Y ist dabei der Display-Filter, -f wäre der Capture-Filter. Die Unterscheidung aus dem Abschnitt weiter oben gilt hier genauso, nur eben mit anderen Buchstaben.
Eine Einschränkung gehört an dieser Stelle ehrlich dazu: Bei verschlüsseltem Verkehr siehst du nur die Hülle. Von einem TLS-Stream bleiben dir Paketgrößen, Timing, Flags und die Handshake-Parameter — also genau das, was für Netzdiagnose zählt. Nutzdaten liest du nur dann mit, wenn du einen TLS-Schlüssel in Wireshark hinterlegst, und das setzt einen Zugriff auf den Sitzungsschlüssel voraus, den du im laufenden Betrieb eines Produktivservers in der Regel nicht hast und auch nicht haben willst. Für die Frage „warum ist es langsam“ brauchst du ihn ohnehin nicht: Ein langsamer Server antwortet langsam, ein langsames Netz liefert Pakete spät. Beides kannst du an der verschlüsselten Hülle ablesen. Wenn du dieselbe Zeile dreißigmal tippst, lohnt sich ein kleines Shell-Skript — und wenn die Zahlen immer größer werden, hilft der bitcalc Downloadzeit-Rechner beim Gefühl dafür, wie lange der Mitschnitt noch laufen darf, bevor die Zielplatte voll ist.
Der Handshake als Maßband
Bevor du irgendetwas über Latenz sagst, schaust du dir die ersten drei Pakete einer Verbindung an. Der Handshake transportiert nämlich kostenlos ein paar Werte, die später alles erklären:
Im SYN bietet der Client seine MSS an, die größte Nutzdatengröße, die er empfangen kann. Übliche Werte sind 1460 bei einer MTU von 1500 auf Ethernet, 1440 bei einem gesetzten DF-Bit und 1380 oder weniger durch einen VPN-Tunnel. Die Window Scale-Option vergrößert das Empfangsfenster über die 16 Bit hinaus, die das TCP-Header-Feld hergibt; ohne sie ist bei 64 KiB Schluss. Und die Zeitdifferenz zwischen SYN und dem ACK des Clients ist deine erste, sehr ehrliche RTT-Messung, bevor eine einzige Nutzlast geflossen ist.
Wenn du diese drei Werte zweier Server vergleichst, findest du erstaunlich oft die Ursache für „langsame Anwendung“, ohne eine Zeile Anwendungscode zu lesen. Eine kleine MSS im Handshake heißt fast immer: Da steckt ein Tunnel oder eine Zwischenbox mit kleinerer MTU im Weg. Details zu dieser Klasse von Problemen stehen im Artikel MTU, MSS & Jumbo Frames; hier genügt: Der Mitschnitt zeigt dir die kleine MSS, und die Erklärung liefert der MTU-Artikel.
Retransmits lesen: Verlust, Reordering oder Duplikat
Ein Retransmit ist kein Urteil, sondern eine Beobachtung. Wireshark markiert ein Paket dann als Wiederholung, wenn es eine Sequenznummer sieht, die es in diesem Datenstrom schon einmal gesehen hat. Drei Ursachen sind üblich, und sie unterscheiden sich im Mitschnitt sauber:
- Echter Verlust: Nach dem Original kommt ein ganzes Stück Nichts, dann die Wiederholung nach etwa der RTO. Typisch sind hier RTO-Werte um 200 Millisekunden und aufwärts, weil das unter Linux das Minimum ist. Ursache ist ein überlastetes Segment, ein defekter Uplink oder ein voller Puffer auf dem Weg.
- Fast Retransmit: Der Sender wiederholt, sobald drei Duplikat-ACKs ankommen, also viel früher als nach dem Timeout. Wireshark zeigt das als
fast_retransmission. Das ist die normale Reaktion des Stacks und bedeutet nur, dass genau ein Paket verloren ging — kein Alarm. - Reordering: Pakete kommen in anderer Reihenfolge an, als sie gesendet wurden. Der Client sieht eine Nummer zu früh und sendet einen Duplikat-ACK, die Wiederholung erledigt sich aber von selbst. Ursache ist oft ein Link-Aggregation-Bundle, das ohne Flow-Affinität arbeitet.
Die drei auseinanderzuhalten gelingt dir, indem du dir die Sekunden zwischen Original und Wiederholung ansiehst. Wenige Millisekunden und drei Duplikat-ACKs davor: Fast Retransmit. Rund 200 Millisekunden und Stille davor: echter Verlust mit Timeout. Reihenfolge durcheinander, aber die Wiederholung ist fast gleichzeitig mit dem Original: Reordering. Diese Lesart ist wichtiger als die absolute Zahl der Retransmits: Ein Prozent Wiederholungen bei gleichmäßiger Verteilung über alle Ströme ist ein Lastproblem, ein einzelner Strom mit fünfzig Prozent Wiederholungen ist ein Pfadproblem.
Latenzquellen trennen
Wenn ein Benutzer „langsam“ sagt, meint er fast immer eines von drei Dingen, und der Mitschnitt kann sie auseinanderhalten. Die erste Quelle ist die Transportstrecke: RTT, Retransmits, Reordering. Die zweite ist der Empfänger, sichtbar als Zero-Window-Fenster, wenn die Anwendung nicht schnell genug aus dem Socket liest oder der Puffer voll ist. Die dritte ist die Anwendung selbst, also die Zeit zwischen dem letzten Datenpaket einer Anfrage und dem ersten Antwortpaket des Servers.
Für die erste Quelle nutzt du tcp.analysis.ack_rtt, das Wireshark für jedes ACK berechnet. Für die zweite filterst du auf tcp.analysis.zero_window und findest sofort die Verbindungen, die unter Speicherdruck gestanden haben. Für die dritte markierst du in Wireshark die letzte Datenanfrage und gehst mit „Set/Next Time Reference“ auf das erste Antwortpaket — die angezeigte Differenz ist die Denkzeit des Servers, und die ist manchmal erstaunlich groß. Ich habe Kundenfälle gesehen, bei denen von 900 Millisekunden Antwortzeit 830 auf die Applikation entfielen und nur 70 auf das Netz. Ohne diese Trennung diskutiert man tagelang mit dem Netzwerkteam, obwohl das Problem in der Datenbankabfrage liegt.
VPN- und MTU-Fallen im Mitschnitt
Mitschnitte über VPN-Strecken sind besonders lehrreich und besonders tückisch. Auf dem VPN-Interface siehst du die verschlüsselten Pakete mit ihrer eigenen Länge, auf dem LAN-Interface daneben ist die Nutzlast schon wieder ausgepackt. Wenn du auf der einen Seite eine Latenz misst und auf der anderen nicht, hast du gerade bewiesen, dass der Tunnel selbst die Ursache ist — Bündelung, Verschlüsselung und WAN-Strecke laufen dort sichtbar getrennt.
Zwei Klassiker in diesem Zusammenhang. Erstens: Ein Benutzer im Homeoffice meldet langsame Downloads, im Büro ist alles fein. Der Mitschnitt am Server zeigt normale RTTs, der Mitschnitt am Client aber große. Dazwischen liegt nur der Tunnel, also ist die WAN-Strecke der Flaschenhals und nicht der Server. Zweitens: Die schon erwähnte kleinere MSS im Handshake bei DHCP-Option-140-Umgebungen, bei der ein Rechenzentrum pro Seite unterschiedliche Werte setzt. Hier lohnt sich für das Verständnis der MTU-Grundlagen der oben verlinkte Artikel, und für das nachrechenbare Ergebnis der Blick auf die tatsächliche Paketgröße im Mitschnitt: Ein Datenpaket von 1448 Bytes bei einem 1500er Link ist normal, eines von 1352 Bytes verrät einen Tunnel mit 1400er MTU.
Datenschutz: wie lange darf ein Mitschnitt liegen?
Ein Mitschnitt ist eine Sammlung personenbezogener Daten, sobald darin Nutzerverkehr steckt. In einem Mitschnitt sieht man besuchte Webseiten, gesendete Mail-Header, bei unverschlüsseltem Verkehr sogar Inhalte. In Deutschland ist das ausdrücklich ein Fall für die Datenschutz-Folgenabschätzung, und die Aufbewahrung ist das praktische Problem. Die Regeln, mit denen ich in Kundensystemen fahre:
- Zweck an den Zeitraum binden. Ein Mitschnitt entsteht zur Störungsanalyse und wird gelöscht, wenn die Störung dokumentiert ist. Ich schreibe mir das Datum in den Dateinamen, nicht in eine separate Liste, die ich nicht wiederfinde.
- Fristen setzen und automatisieren. Ein Löschjob ist zuverlässiger als Disziplin. Bei uns fliegen Capture-Dateien aus dem Arbeitsverzeichnis nach 30 Tagen raus; die dokumentierte Ursache bleibt, die Datei nicht.
- Nur so breit wie nötig mitschneiden. Ein Capture-Filter auf einen Host und einen Port erzeugt nicht nur eine kleinere Datei, sondern auch weniger Datenschutzrisiko. Das ist der angenehme Fall, in dem Sauberkeit und Handwerk dasselbe Ziel haben.
- Zugriff beschränken. Capture-Dateien gehören auf Server, auf die nur das Admin-Team kommt, und nicht in einen geteilten Ordner. Wenn ich eine Datei weitergebe, gebe ich nicht den Rohmitschnitt weiter, sondern einen Auszug mit den relevanten Paketen.
Der letzte Punkt hat einen angenehmen Nebeneffekt: Ein auf zwei Sekunden und dreißig Pakete gekürzter Auszug ist auch für das Gegenüber in der Ticketbeschreibung viel leichter zu lesen als eine Megabyte-Datei. Datenschutz macht die Analyse nebenbei benutzbarer.
Der Werkzeugkasten für die Schublade
Wenn du das alles in eine handliche Reihenfolge bringen willst, hilft dieser Ablauf, der bei mir fast immer funktioniert:
- Frage schärfen: Ein Satz genügt. „Zwischen Client und Server kommen Datenpakete doppelt an.“
- Grob mitschneiden: auf dem richtigen Interface, mit
-nn, mit einemhost- odernet-Ausdruck, in eine Datei. Kein Portgewurstel im Capture-Filter. - Vorspielen:
capinfosfür Zeitraum und Menge, dann in Wireshark den Handshake einer betroffenen Verbindung suchen. - Handshake lesen: MSS, Window Scale, erste RTT. Das sind deine drei Grundwerte.
- Display-Filter setzen:
tcp.analysis.retransmission, dannack_rtt, dannzero_window. Immer einzeln, sonst siehst du nichts. - Zeitreferenz nutzen: letzte Anfrage markieren, erste Antwort ansehen, Denkzeit vom Netz trennen.
- Ergebnis sichern: den gekürzten Auszug ins Ticket, die Rohdatei nach Frist löschen.
Für die Adress- und Netzfragen in Schritt zwei greife ich regelmäßig zum Subnetz-Rechner, weil ein falsch gerechnetes net im Capture-Filter am Ende bedeutet, dass du eine Stunde lang nichts gefiltert hast. Und wenn der Mitschnitt lang laufen soll, gibt der Downloadzeit-Rechner ein Gefühl für die Datenmenge, bevor die Partition voll ist.
Fazit
Paketanalyse hat bei vielen Admins ein Image als letztes Mittel, wenn gar nichts mehr geht. Dabei ist sie das Gegenteil: das billigste Werkzeug für die Frage, wo genau die Wahrheit liegt. Ein Mitschnitt ist in dreißig Sekunden gestartet, er braucht keine Lizenz, keinen Agent auf dem Zielsystem und keine Freigabe vom Hersteller. Er nimmt den Geräten im Weg ihre Ausrede ab und liefert Zahlen, über die man reden kann.
Was du dafür wirklich brauchst, ist erstaunlich wenig: die Trennung von Capture- und Display-Filter im Kopf, tcpdump -i -nn -w auf einem Server, Wireshark mit den vier tcp.analysis-Feldern und die Bereitschaft, den Handshake als Maßband ernst zu nehmen. Der Rest ist Übung. Der Fall mit dem ERP hat fünf Minuten Analyse gekostet, nachdem ich endlich Daten hatte, und zwei Stunden in dem Moment, in dem ich noch geraten habe. Seitdem gilt bei mir: Erst mitschneiden, dann diskutieren.