Wenn bei Netzwerkproblemen geflucht wird, geht der Blick fast immer nur in eine Richtung: von A nach B. ping läuft, traceroute steht irgendwann, der Port antwortet drüben nicht. Das Paket schlägt auf dem Zielsystem auf — tcpdump zeigt es an —, und damit gilt das Netzwerk gedanklich als erledigt. Wenn die Anwendung drüben nicht antwortet, landet der schwarze Peter schnell bei ihr.
Das ist einer der typischen Denkfehler auf Linux-Systemen.
Nicht weil die Werkzeuge lügen, sondern weil wir aus einer richtigen Teilantwort voreilig den Gesamtzustand ableiten. Ein positiver Befund sagt zunächst nur etwas über genau den Punkt aus, den man gerade geprüft hat.
Der tcpdump-Trugschluss
Der Trugschluss bei tcpdump liegt an seiner Position im System. Der Paketmitschnitt greift direkt an der Schnittstelle an. Ein Paket, das tcpdump dort anzeigt, ist deshalb noch lange nicht bei der Anwendung angekommen — der Kernel verarbeitet es danach weiter und kann es auf dem verbleibenden Weg immer noch stumm verwerfen.
Ankommende TCP-SYNs zeigt tcpdump brav an. Eine Millisekunde später verwirft der Kernel das Paket aus irgendeinem Grund. Die Anwendung am lokalen Socket bekommt davon überhaupt nichts mit: Sie hat kein SYN gesehen und schickt folglich kein SYN-ACK. Wer nur dem Mitschnitt an der Schnittstelle vertraut, sieht nicht, was der Kernel danach damit tut.
Ein prägnantes Beispiel für dieses Verhalten ist das Reverse Path Filtering ( rp_filter). Vereinfacht gesagt prüft der Kernel dabei, ob die Quelladresse über die Schnittstelle erreichbar wäre, auf der das Paket gerade angekommen ist. Im Strict Mode muss diese Schnittstelle zum besten Rückweg passen. Tut sie das nicht, fliegt das Paket stillschweigend raus — ohne Log-Eintrag, ohne ICMP Unreachable und ohne TCP-RST.
Sowohl bei Hosts mit mehreren Netzwerkinterfaces als auch im Umfeld von VPN-Tunneln, Container-Bridges oder komplexeren Routing-Tabellen können sich schnell Konstellationen mit asymmetrischem Traffic ergeben. Anfragen kommen über eine Schnittstelle rein, während die Antwort laut Routing-Tabelle über eine andere rausgehen würde. rp_filter greift ein, und die Verbindung stirbt, noch bevor ein Socket davon erfahren hat.
Korrekte Antworten, falsche Schlüsse
Das Grundproblem beschränkt sich allerdings nicht auf den Reverse Path Filter.
Es zieht sich durch nahezu alle Werkzeuge, die man bei der Fehlersuche einsetzt: Sie antworten zwar technisch korrekt, aber oft auf eine ganz andere Frage als die, die man eigentlich im Kopf hatte.
tcpdump bestätigt nur, dass ein Paket an der beobachteten Schnittstelle sichtbar war. ping zeigt lediglich, dass der IP-Stack der Gegenstelle ICMP-Echos beantwortet — sagt aber rein gar nichts darüber aus, ob auf Port 443 ein Dienst zuhört oder eine Firewall TCP-Traffic verwirft.
Ähnlich sieht es direkt auf dem Host aus. systemctl meldet fröhlich einen aktiven Dienst, weil der Prozess läuft. Wenn die Anwendung aber nur an 127.0.0.1 lauscht oder nach einem Interface-Wechsel noch an einer alten Adresse hängt, schlagen externe Verbindungsversuche trotzdem fehl, bevor überhaupt ein Byte verarbeitet wird. Das Werkzeug zur Prozessüberwachung meldet Grün, während am Netzwerk-Socket Funkstille herrscht.
Namensauflösung und Verbindungslogik
Ein weiteres erprobtes Feld für solche Fehlschlüsse ist die Namensauflösung.
Wenn die Verbindung zäh wirkt, greift der erste Reflex meist zu dig oder nslookup. Wenn das Werkzeug nach zwei Millisekunden eine saubere Antwort liefert, haken viele das Thema DNS ab: Die IP steht da, also muss der Fehler woanders liegen.
Auch hier beantwortet das Werkzeug nur eine sehr spezifische Frage. dig schickt eine direkte DNS-Anfrage an den konfigurierten Resolver. Es ignoriert lokale Hostdateien genauso wie die Systemregeln, nach denen Namensabfragen eigentlich abgearbeitet werden, und hat nichts damit zu tun, wie die Anwendung das Ergebnis am Ende selbst bewertet.
Liefert der Nameserver beispielsweise sowohl A- als auch AAAA-Records zurück, der IPv6-Pfad im Netzwerk ist aber nicht sauber durchgeroutet oder verendet unterwegs, hängt die Anwendung. Je nachdem, wie der Client mit den Antworten umgeht — ob modernes Happy Eyeballs oder langes Abwarten bis zum Timeout —, verstreichen Sekunden, bis der Fallback auf IPv4 greift. Nach außen wirkt das System wie ein träges Netzwerk. dig hatte völlig recht: Der Name lässt sich auflösen.
Nur sagt das wenig darüber aus, wie der Prozess die Adresse in der Praxis ansteuert. Wie wichtig ein sauber durchdachtes DNS- und Routing-Konzept in der Praxis ist, hat sich für mich auch wieder beim Aufbau meiner PowerDNS-Architektur im Homelab gezeigt.
Mit den Jahren verändert sich deshalb weniger die Werkzeugkiste als der Reflex bei der Fehlersuche. Man lernt, den ersten Befund nicht mehr als Beweis zu nehmen, sondern als Indiz. Nicht weil die Werkzeuge unzuverlässig wären, sondern weil ein Linux-System aus vielen Schichten besteht, die sich gegenseitig beeinflussen.
Wo sich Beobachtungen trennen
Wenn zwei Werkzeuge scheinbar gegensätzliche Signale liefern, widersprechen sie sich nicht zwangsläufig.
Wenn ss einen Listener zeigt und tcpdump gleichzeitig ankommende Pakete sieht, die Verbindung aber trotzdem nicht zustande kommt, beobachten die Werkzeuge lediglich unterschiedliche Stellen der Kette. Gerade in solchen Momenten liegt die Information nicht im einzelnen Befund, sondern in der Lücke dazwischen. Statt auf Verdacht Konfigurationen anzupassen oder nach einer auffälligen Ausgabe direkt loszugraben, geht es vor allem darum herauszufinden, an welchem Punkt die Verarbeitung zwischen den beiden Beobachtungen abreißt.
Wer mehr Granularität auf Socket-Ebene braucht, als ein Interface-Dump liefert, findet in modernen eBPF-Ansätzen oft die nötige Tiefe (siehe auch: Little Snitch auf Linux: Netzwerk-Kontrolle durch eBPF).
Wenn es im Ticket oder im Chat mal wieder heißt, das Netzwerk ist kaputt, hat sich an meiner ersten Reaktion über die Jahre wenig geändert. Meistens stimmt die Aussage sogar — nur eben selten in dem Sinne, wie sie gemeint war. Es ist selten der Switch, der den Geist aufgegeben hat, oder das Kabel, das jemand gezogen hat.
Und manchmal ist es schlicht ein System, das exakt das tut, wofür es konfiguriert wurde.
Nur leider nicht das, was man selbst gerade von ihm erwartet hat. Das macht die Fehlersuche zwar nicht zwingend kürzer, spart aber zumindest das blinde Stochern. Man hört auf, auf Verdacht Firewalls umzukonfigurieren, und fängt an herauszufinden, an welcher Stelle sich das Verhalten des Systems von den eigenen Erwartungen trennt.