Das klassische Tcpdump gehört zum täglichen Rüstzeug von Admins, ist jedoch schon etwas in die Jahre gekommen. Das eBPF-basierte Ptcpdump will diesen Makel beheben: Der Rewrite bietet weitgehende CLI-Kompatibilität und kann obendrein Prozessinformationen anzeigen.
Wohl jeder Sysadmin, der regelmäßig Linux-Systeme betreut, hat im Laufe seiner Karriere schon einmal zu Tcpdump gegriffen, um einem Netzwerkproblem auf die Schliche zu kommen. Oft gilt das als Ultima Ratio, wenn keine Netzwerkverbindung zustande kommt, obwohl alle anderen Debugging-Mechanismen ausgeschöpft und alle möglichen Einstellungen überprüft sind. Dann steht eine tiefgehende Fehlersuche mit Tcpdump [1] auf dem Plan (Abbildung 1).

Abbildung 1: Tcpdump gilt unter Linux als absolutes Standardwerkzeug, kann aber die Quell- und Zielprozesse des Traffics nicht anzeigen.
Dass sich mitgeschriebene Dumps im Pcap-Format [2] speichern und dann beispielsweise in Wireshark grafisch darstellen lassen, ist den meisten Admins bekannt. Ebenso wissen die meisten Nutzer, dass sich mittels Optionen wie »-i« und »-nv« sowohl der Umfang der Meldungen bestimmen als auch auf bestimmte Netzwerkschnittstellen beschränken lässt. Dass Tcpdump zudem ein umfassendes Filter-Framework mitbringt, mit dem sich der zu analysierende Netzwerkverkehr sehr genau eingrenzen lässt, haben aber nur wenige Anwender im Hinterkopf.
Dagegen ärgern sich viele Tcpdump-Anwender darüber, dass sich mit Tcpdump der Netzwerkverkehr nicht mit bestimmten Prozessen zuordnen lässt: Das Werkzeug kann nicht anzeigen, zu welchem Programm die aufgezeichneten Pakete gehören. Als Workaround lassen sich anhand von IP-Adressen und eingehenden wie ausgehenden Ports teilweise die Programme identifizieren. Das ist jedoch aus mehreren Gründen nicht besonders praktisch: Einerseits kann man die Informationen so nicht zusammen weiterverarbeiten, andererseits hantiert man bei dieser Vorgehensweise ständig mit diversen Werkzeugen parallel in der Shell.
Die Ursache dafür, dass Tcpdump den Netzwerkverkehr nicht einzelnen Programmen zuordnen kann, ist banal: Es schaltet zu überwachende Netzwerkschnittstellen zunächst in den Promiscuous Mode, um sämtliche eingehenden Pakete zu Gesicht zu bekommen. Damit umgeht es einen Teil der Sicherheitsfunktionen, die der Linux-Kernel für das Belauschen von Netzwerkverbindungen eigentlich vorschreibt. Auf der Netzwerkebene bietet Linux selbst dann keine Features, um Programme und Traffic zu korrelieren.
Überdies gibt es in Tcpdump keinen Code, um entsprechende Informationen im System zusammenzutragen und auszugeben. Daher kann man das Programm auch nicht anweisen, nur Pakete an oder von bestimmten Programmen mitzulesen. Hier liegt das Problem ebenfalls eher beim Linux-Kernel, dessen Netzwerk-Layer keine entsprechenden Filter umfasst.
eBPF bietet Alternativen
Vieles hängt an dieser Stelle daran, dass sowohl der entsprechende Linux-Code als auch Tcpdump bereits einige Lenze auf dem Buckel haben. Als Tcpdump für Linux entstand, bot der Kernel nicht annähernd die umfassende Funktionalität gegenwärtiger Versionen. Zwar wäre es theoretisch möglich gewesen, sowohl das Werkzeug als auch den Kernel so umzubauen und aufeinander abzustimmen, dass die benötigten Funktionen entstanden wären. Getan hat diese Arbeit bislang aber niemand, wohl auch, weil die entsprechenden Modifikationen im Kernel langwierig und kompliziert wären. Obendrein pocht Linus Torvalds darauf, dass neue Funktionen im Kernel vorhandene Technologien nutzen, wo immer möglich.
Wer sich mit dem Netzwerk-Layer von Linux ein wenig auskennt, hat an dieser Stelle vermutlich augenblicklich eine Idee: In Form von eBPF existiert im Kernel schließlich seit Jahren eine VM-Umgebung, die beliebige Software aus dem Userland laden und ausführen kann. Dabei erhalten Programme, die via eBPF in Linux agieren, Komplettzugriff auf den gesamten Kernel-Space, sofern der Administrator das entsprechend einrichtet.
Der Extended Berkeley Packet Filter trägt seine Kernfunktion ja bereits im Namen. So lassen sich mittels eBPF umfassende Firewall-Implementierungen im Kernel schaffen, die nicht auf das bei vielen wenig beliebte Netfilter und mithin auf Nftables oder Iptables setzen. Wirklich eingreifen muss eBPF in den Netzwerkverkehr innerhalb des Kernels aber nicht, es kann seine Rolle auf die eines Protokollanten beschränken. Das ermöglicht es, eine Tcpdump-Alternative auf eBPF-Basis zu schaffen, die sowohl den gesamten Datenverkehr sieht als auch auf die PID-Tabellen im Kernel Zugriff hat.
Ptcpdump
An ebendieser Stelle greift Ptcpdump ins Geschehen ein (Abbildung 2) und verspricht im Wesentlichen genau das Gewünschte: Die Software agiert als In-Kernel-VM auf eBPF-Basis, die den Traffic einzelner Prozesse identifizieren und untersuchen kann. Dabei bleibt sie erfreulicherweise weitgehend CLI-kompatibel zu Tcpdump.

Abbildung 2: Ptcpdump tritt als moderne, mit Go entwickelte Alternative zu Tcpdump an. Das Tool zeigt eine sehr ähnliche Ausgabe, allerdings mit vollständiger Prozessinformation.
Sonderlich verbreitet ist Ptcpdump bislang nicht. Sucht man im Netz danach, stößt man auf das entsprechende Github-Verzeichnis [3] von Huang Huang, dem Hauptautor des Werkzeugs. Ptcpdump steht als quelloffene Software unter der MIT-Lizenz. Es fußt konzeptionell auf Skbdump [4], einem weiteren Paketuntersucher auf eBPF-Grundlage, den jschwinger233 in C verfasst hat. Der Autor verlor allerdings schon bald nach der Fertigstellung der ersten Versionen von Skbdump das Interesse an seinem Werkzeug, obwohl er nach wie vor im eBPF-Universum aktiv ist.
Bei Ptcpdump sieht das anders aus: Auch Huang Huang operiert im eBPF-Dunstkreis, hat sein Tool allerdings komplett neu in Go geschrieben und entwickelt es aktiv weiter. Es bietet bereits jetzt diverse Features, die für Skbdump vorgesehen waren, aber nie fertig wurden. Dazu zählt unter anderem das Mitschneiden von Paketen von virtuellen, auf Softwareebene simulierten Netzwerkgeräten (TUN-Devices). Gerade wer viel mit Containern oder regulären VMs hantiert, braucht TUN-Unterstützung dringend.
Während Skbdump nur wenige CLI-Optionen von Tcpdump übernommen hat oder überhaupt unterstützt, macht Huang Huang das bei Ptcpdump anders: Der Entwickler hat das Werkzeug mehr oder weniger als direkten Ersatz für Tcpdump vorgesehen.
CLI-Kompatibilität
Schicken Werkzeuge wie Ptcpdump sich an, etablierte Vorgänger zu ersetzen, stellt sich stets die Gretchenfrage nach der Kompatibilität auf Kommandozeilenebene. Viele Administratoren kennen die CLI-Aufrufe für die wichtigsten, im Alltag häufig genutzten Tools auswendig.
Wer etwa den Datenverkehr eines Interfaces mitschneiden und im Anschluss mit Wireshark untersuchen möchte, ruft so etwas wie »tcpdump -nv -i Interface -w trace.pcapng« auf. Oft nutzen Admins die entsprechenden Befehle in Shell-Skripts oder haben sie als Aliase konfiguriert. Beim Ersatz eines Tools durch ein anderes laufen all diese Aliase und Skripts ins Leere, wenn das Nachfolgewerkzeug die verwendeten Kommandozeilenparameter nicht kennt oder sie für andere Funktionen einsetzt.
Wer die Rust-Fangemeinde kennt, weiß, dass es dort diverse Projekte gibt, um alteingesessene Werkzeuge für die Kommandozeile durch modernere und oft schnellere Alternativen zu ersetzen. Dabei lassen sich zwei Kategorien von Programmen unterscheiden: Die einen bauen die Funktionen mehr oder weniger ähnlich nach, die anderen versprechen echte und vollständige CLI-Kompatibilität. Wer etwa die Uutils installiert, bekommt ein Binary »udf«, das parameterkompatibel zu GNUs »df« agiert.
Huang Huang hat für Ptcpdump denselben Ansatz gewählt und die allermeisten Parameter aus Tcpdump übernommen. So legt »ptcpdump -nv -i Interface -w trace.pcapng« ebenfalls eine Pcap-Datei mit entsprechendem Inhalt an. Eine vollständige Übersicht aller CLI-Parameter von Tcpdump und dem Grad ihrer Unterstützung in seinem Werkzeug stellt Huang Huang im Github-Verzeichnis von Ptcpdump zur Verfügung.
Unterschiede hinsichtlich der unterstützten Optionen ergeben sich vor allem bei jenen Features, die eines der beiden Tools nicht bereitstellt. So unterstützt Ptcpdump beispielsweise den Parameter »–pid«, um den Traffic einer bestimmten PID zu verfolgen, bei Tcpdump fehlt logischerweise eine Entsprechung. Den umgekehrten Fall gibt es ebenso: Für Tcpdump lässt sich festlegen, ob der Promiscuous Mode zum Einsatz kommen soll. Den unterstützt Ptcpdump erst gar nicht, weil er in eBPF so nicht zur Verfügung steht.
Zu tatsächlichen Problemen im Alltag können die Schalter »-vv«/»-vvv« sowie »-tt«/»-ttt« führen. Der erste sorgt bei Tcpdump für eine besonders ausführliche Ausgabe, der zweite zeigt im Pcap-File besonders genaue Deltas für die Zeitstempel zweier aufeinanderfolgender Zeilen an. Alle vier Steigerungsmöglichkeiten beherrscht Ptcpdump nicht, hier muss ein schlichtes »-v« oder »-t« genügen.
Genau hingesehen
Das recht junge Ptcpdump liegt den meisten gängigen Distributionen noch nicht bei. Auf der Github-Seite des Projekts finden sich einsatzbereite Binärdateien für die Architekturen x86_64 sowie ARM64. Mit einer entsprechenden Build-Umgebung für Go lässt sich das Werkzeug auch vor Ort übersetzen, komfortabel ist das aber nicht. Für den Einsatz auf anderen Architekturen haben Sie allerdings zumindest im Moment keine andere Möglichkeit.
Für die Installation des Programms genügt es, den Tarball herunterzuladen, zu entpacken und »ptcpdump« nach »/usr/local/bin/« zu verschieben (Abbildung 3). Danach kann es mit dem Verfolgen von Datenströmen losgehen, da das zwingend benötigte eBPF auf allen modernen Distributionen vorhanden und aktiviert ist. Anders als sein Vorgänger arbeitet Ptcpdump im Augenblick nur unter Linux: Auf vielen anderen Betriebssystemen, auf denen Tcpdump per Promiscuous Mode funktioniert, steht eBPF nicht zur Verfügung.

Abbildung 3: Zur Installation des Werkzeugs genügen das Entpacken des heruntergeladenen Tarballs und das Verschieben der Programmdatei nach »/usr/local/bin/«.
Passionierte Sysadmins erschrecken beim ersten Aufruf von Ptcpdump möglicherweise, denn auf Systemen ohne Docker-Laufzeitumgebung wirft das Tool erst einmal mit Fehlermeldungen um sich. Keine Sorge: Das beeinträchtigt die Funktionalität nicht, sondern zeugt von einem weiteren Ptcpdump-Feature, das gerade in Kubernetes-basierten Umgebungen ausgesprochen praktisch ist: die native Integration in Container-Workloads.
Auch ein Container läuft auf seinem System ja als ganz normaler Prozess mit eigener PID. Hinter den Kulissen verfügt Docker aber bekanntlich über ein relativ komplexes Gestrüpp aus Bridges und anderen Arten von Netzwerk-Interfaces. Die könnte der Administrator mit Tcpdump selbst durchforsten, um den Netzwerkverkehr eines bestimmten Containers zu sehen. Ptcpdump erspart ihm das durch eine native Integration sowohl in Docker als auch in Kubernetes: Der Admin gibt nur noch die PID oder ID des zu überwachenden Containers an. Um den Rest kümmert sich der Sniffer automatisch, sofern die Docker-Laufzeitumgebung installiert und aktiv ist.
Wer schon einmal versucht hat, den Datenverkehr eines Containers auf konventionellem Weg zu untersuchen, weiß, welch mühsames Unterfangen das bisweilen sein kann. Hier bringt Ptcpdump einen erheblichen Gewinn an Funktionalität und Komfort.
Ausgabeformate
Ptcpdump kann den Administrator durchaus mit Informationen erschlagen, muss das aber nicht. Ein paar Beispiele sollen das verdeutlichen.
Rufen Sie das Werkzeug ohne spezifische Parameter hinsichtlich der Ausgabe auf, listet es in der Ausgabe ganz einfach den Namen des Prozesses auf sowie die als Quelle oder Ziel des Traffics identifizierte PID. Im ersten Beispiel aus Listing 1 sehen Sie den Datenverkehr des Prozesses »wget« mit der Prozess-ID »3533008«. Er stammt aus einem Docker-Container namens »test«, der seinerseits zum Pod »test.default« gehört.
Listing 1
Ausgabebeispiele
### Beispiel 1
9:32:09.718892 vethee2a302f wget.3553008 In IP 10.244.0.2.33426 > 139.178.84.217.80: Flags [S], seq 4113492822, win 64240, length 0, ParentProc [python3.834381], Container [test], Pod [test.default]
09:32:09.718941 eth0 wget.3553008 Out IP 172.19.0.2.33426 > 139.178.84.217.80: Flags [S], seq 4113492822, win 64240, length 0, ParentProc [python3.834381], Container [test], Pod [test.default]
### Beispiel 2
09:32:09.718892 vethee2a302f wget.3553008 In IP 10.244.0.2.33426 > 139.178.84.217.80: tcp 0, ParentProc [python3.834381], Container [test], Pod [test.default]
09:32:09.718941 eth0 wget.3553008 Out IP 172.19.0.2.33426 > 139.178.84.217.80: tcp 0, ParentProc [python3.834381], Container [test], Pod [test.default]
### Beispiel 3
13:44:41.529003 eth0 In IP (tos 0x4, ttl 45, id 45428, offset 0, flags [DF], proto TCP (6), length 52)
139.178.84.217.443 > 172.19.0.2.42606: Flags [.], cksum 0x5284, seq 3173118145, ack 1385712707, win 118, options [nop,nop,TS val 134560683 ecr 1627716996], length 0
Process (pid 553587, cmd /usr/bin/wget, args wget kernel.org)
ParentProc (pid 553296, cmd /bin/sh, args sh)
Container (name test, id d9028334568bf75a5a084963a8f98f78c56bba7f45f823b3780a135b71b91e95, image docker.io/library/alpine:3.18, labels {"io.cri-containerd.kind":"container","io.kubernetes.container.name":"test","io.kubernetes.pod.name":"test","io.kubernetes.pod.namespace":"default","io.kubernetes.pod.uid":"9e4bc54b-de48-4b1c-8b9e-54709f67ed0c"})
Pod (name test, namespace default, UID 9e4bc54b-de48-4b1c-8b9e-54709f67ed0c, labels {"run":"test"}, annotations {"kubernetes.io/config.seen":"2024-07-21T12:41:00.460249620Z","kubernetes.io/config.source":"api"})
Haben Sie es lieber etwas kompakter, übergeben Sie beim Aufruf den Schalter »-q« (Listing 1, zweites Beispiel). Dann entfallen Details hinsichtlich der TCP/IP-Sequenznummern und der Verbindungs-Flags, alle zentralen Informationen über die involvierten Prozesse im System bleiben aber enthalten.
Wünschen Sie eine besonders ausführliche Ausgabe, verwenden Sie statt »-q« den Schalter »-v« (Listing 1, drittes Beispiel). Dann liefert Ptcpdump sämtliche gesammelten Informationen inklusive der Details zu den ursprünglichen Containern, deren PIDs, den zugehörigen K8s-Namespaces und so weiter.
In der Ausgabe lässt sich gut erkennen, dass Ptcpdump eben nicht nur Details aus der Containerlaufzeitumgebung auf dem System ausliest, sondern auch die Annotationen von Kubernetes erkennt und interpretiert (Abbildung 4). Über entsprechende Schalter blenden Sie bei Bedarf zudem bestimmte Details spezifisch ein oder aus. Der Parameter »–context=process« beispielsweise würde lediglich die »Process«-Zeile mitanzeigen, »–context=process,container« zusätzlich die zum Container und so weiter.

Abbildung 4: Ptcpdump beherrscht den Umgang mit Containern und kann sogar Annotationen direkt aus Kubernetes auslesen. Quelle: Huang Huang
In Summe lassen Sie sich von Ptcpdump genau das Level an Information liefern, das Sie für das Debugging benötigen. Noch praktischer wäre es, könnte das Tool sich direkt mit Kubernetes verbinden und Informationen zu den zu untersuchenden Containern von dort dynamisch auslesen. Im Augenblick klappt das jedoch noch nicht.
Geschwind ans Werk
Eine im Netz viel geäußerte Sorge hinsichtlich der Funktionalität von Ptcpdump bezieht sich übrigens auf die Performance des Werkzeugs. Weil das Tool mehr Informationen vom laufenden System benötigt, um seine Anzeige zusammenzubauen, als es bei seinem betagten Vorgänger der Fall war, dauert der Vorgang länger. Obendrein muss das Programm diese Daten bei jeder angezeigten Zeile korrelieren.
In der Praxis wirkt sich das auf die Arbeitsgeschwindigkeit aber praktisch nicht aus. Wer auf seinem System keine Probleme mit Tcpdump hat, bekommt auch mit Ptcpdump keine. Alle Ausgaben erfolgen in Echtzeit, das Tool gerät beim Schreiben der Datenflut auf der Kommandozeile nicht ins Straucheln. Wie der Vorgänger erlaubt es auf Wunsch sogar, die gesammelten Informationen direkt per Pipe an eine Instanz von Tshark oder Wireshark auszugeben, sodass die Daten sich dort praktisch in Echtzeit untersuchen lassen.
Zweifellos spielt eBPF dabei eine Rolle, denn die unter Linux genutzte Implementierung der Technik gilt unter Fachleuten als ausgesprochen schlank und leistungsfähig. Sie lässt andere Paketfilter wie Netfilter bei vielen Aufgaben buchstäblich alt aussehen. Das soll die Verdienste von Huang Huang aber nicht schmälern: Selbst ein sehr schnelles Framework hilft nicht, wenn eine schnarchlahme Anwendung es nutzt. Diesen Vorwurf muss Ptcpdump sich indes nicht gefallen lassen.
Bedingt kompatibel
Zwar fußt Ptcpdump auf dem großartigen eBPF und bietet viele Funktionen, die Tcpdump nicht kennt oder nicht implementieren kann. Selbst in seinem Universum ist aber längst nicht alles Gold, was glänzt.
Für Admins, die das Hantieren mit Tcpdump und Wireshark gewohnt sind, ist die augenblicklich noch fehlende Kompatibilität von Pcap-Ausgaben eine Art Showstopper. Das Problem liegt auf der Hand: In Ausgaben von Tcpdump gibt es keine PID-Informationen, und so bietet Wireshark für solche Felder in Pcap-Ausgaben auch keine Unterstützung. Ptcpdump erweitert seine Pcap-Dateien zwar ordnungsgemäß im PCAP-NG-Format [5] um die entsprechenden Felder. Das kann Wireshark auch auslesen, ist jedoch nicht in der Lage, die Informationen dynamisch auszuwerten und etwa die passenden Prozesse gleich live in der Ausgabe (Abbildung 5) anzuzeigen.

Abbildung 5: In der Ausgabe von Wireshark tauchen die Prozessinformationen zwar unter den Packet Comments auf, dynamisch erfolgt die Anzeige letztlich aber nicht.
Wer Wireshark direkt auf dem System aufruft, auf dem die zu untersuchenden Prozesse laufen, würde intuitiv erwarten, dass Wireshark die entsprechenden Daten korreliert. Das erfolgt im Augenblick aber noch nicht. Entsprechend gilt es, hier doch wieder mit einer Mischung aus mehreren Werkzeugen zu arbeiten und alte Bekannte wie Htop oder »ps fauxw« zu Hilfe zu rufen.
Das ist freilich Meckern auf hohem Niveau: Sieht der Administrator in der Wireshark-Ausgabe die involvierten PIDs, kann er die emittierenden Prozesse auf dem betroffenen System schnell ermitteln. Im Kern handelt es sich also lediglich um eine Komforteinschränkung. Möglicherweise beseitigt Huang Huang im Gespann mit den Wireshark-Entwicklern den Missstand aber schon bald. Allzu schwierig wäre das nicht. Zudem hat der Ptcpdump-Autor in den vergangenen Monaten immer wieder flugs auf Feedback seiner Anwender reagiert und Feature-Lücken geschlossen.
Ausblick
Alles in allem präsentiert sich Ptcpdump als weitgehend CLI-kompatible Alternative zum beliebten Urahn Tcpdump. Es lässt sich in den meisten Fällen lokal installieren und dann per Alias voreinstellen. Dass die Installation aktuell noch etwas holprig ist, liegt vermutlich vor allem daran, dass noch kaum jemand das Werkzeug kennt und Pakete für die gängigen Distributionen fehlen. Zwar bereitet die Installation direkt von der Github-Seite des Projekts keine Probleme. Wer als Administrator allerdings in der Produktion mit überwachten Systemen und Compliance-Vorgaben konfrontiert ist, wird diese Option eher vermeiden wollen.
Immerhin: Für Debian GNU/Linux existiert bereits ein Bugreport auf Github, der den Bau eines Debian-Pakets anmahnt. Sobald ein solches existiert, dürfte es umgehend auch in Ubuntu Einzug halten. Für Suse, Red Hat und Konsorten bleibt die Situation dagegen derzeit unklar. Hier kann man nur hoffen, dass mit der zunehmenden Verbreitung von Ptcpdump das Interesse der Distributoren an einer Integration in ihre Plattformen steigt. Ptcpdump wird hier in gewisser Weise zum Verhängnis, dass man tatsächlich unmittelbar auf dem betroffenen System installieren muss, in Form eines Containers lässt es sich nicht sinnvoll ausrollen.
Sobald das Werkzeug in den gängigen Distributionen auftaucht, dürfte seine Fangemeinde wohl sprunghaft wachsen. Das Feedback aus dem Umfeld des Autors ist jedenfalls eindeutig: Dort war Ptcpdump bis dato nicht bekannt, stieß jedoch schon bei der ersten Erwähnung auf großes Interesse. (jcb/jlu)
Infos
- Tcpdump: https://www.tcpdump.org
- Pcap: https://www.tcpdump.org/pcap.html
- Ptcpdump: https://github.com/mozillazg/ptcpdump
- Skbdump: https://github.com/jschwinger233/skbdump
- PCAP Next Generation: https://wiki.wireshark.org/Development/PcapNg






