// Tutorial · Netzwerk · Analyse

tcpdump und Netzwerk-Monitoring unter Debian 13 und CachyOS

📅 22.09.2026 ⏱ 24 Min. Lesezeit

Wenn ein Dienst „langsam“ ist, ein Server „komisch“ sendet oder ein Container „kein Netz“ hat, hilft kein Log weiter – dann muss man die Pakete ansehen. tcpdump ist dafür das Standardwerkzeug, aber es hat drei Hürden: Rechte (es braucht CAP_NET_RAW, nicht zwingend root), Filter (ohne Filter ertrinkt man in Ausgaben) und Auswertung (ein pcap ist nur Rohmaterial). Dieser Artikel zeigt beide Seiten: den gezielten Mitschnitt mit tcpdump unter Debian 13 und CachyOS – und das Monitoring ohne root, das im Alltag meist zuerst hilft: ss, nstat, ethtool, iftop, nethogs, vnstat und sysstat.

Was tcpdump kann – und was nicht

tcpdump setzt auf libpcap auf und fängt Pakete auf der Ebene des Netzwerk-Interfaces ab. Der eigentliche Trick ist nicht das Ausgeben, sondern das Filtern im Kernel: Was nicht passt, wird nie in den Userspace kopiert. Deshalb kann ein einzelner Prozess auf einem 10-Gbit-Link mitschneiten, ohne die Last der Masse zu erzeugen.

Du willst …tcpdump zeigt esWarum
Wissen, ob und wann Pakete ankommenJa, sekundengenau mit ZeitstempelZeitstempel kommen aus dem Kernel (--time-stamp-precision)
Flags, Sequenznummern, Ports, ICMP-TypenJa, vollständig dekodiertlibpcap dekodiert IP, TCP, UDP, ICMP, DNS, HTTP und viele weitere Protokolle
Klartext mitlesen (HTTP, DNS, Mail)Ja, mit -A oder -XDie Nutzlast wird mitgeschrieben
TLS-Inhalt lesenNein – nur Handshake-MetadatenDer Inhalt ist verschlüsselt; sichtbar bleiben SNI, Zertifikatsketten-Größen, Timing
Verläufe über TageNeinKein Speicher, keine Datenbank – dafür sind vnstat und sysstat da
Wissen, welcher Prozess sendetNeinPakete kennen keine PID – dafür ss -p oder nethogs
Reihenfolge im Alltag: zuerst ss und nstat (Kernel-Zähler, keine Rechte nötig), dann tcpdump für den Blick ins Detail. Wer mit dem Mitschnitt anfängt, sucht meistens in 200.000 Zeilen nach dem Problem, das ein ss -tin in einer Zeile gezeigt hätte.

Installation: Debian 13 und CachyOS

tcpdump gehört nicht zur Grundinstallation: auf unserem CachyOS-Testsystem war das Paket nicht vorhanden, und Debian 13 bringt es ebenfalls nicht mit. Beides ist schnell nachinstalliert:

# Debian 13 (Trixie)
sudo apt update && sudo apt install tcpdump

# CachyOS / Arch
sudo pacman -S tcpdump

Auf dem Testsystem läuft tcpdump 4.99.6 mit libpcap 1.11.0 – die Version verrät sich selbst, inklusive der Frage, mit welchem TLS-Stack das Binary gebaut wurde:

tcpdump --version

tcpdump version 4.99.6
libpcap version 1.11.0 (64-bit time_t, with TPACKET_V3)
OpenSSL 3.6.4 25 Aug 2026
64-bit build, 64-bit time_t

Interessant ist die Zeile with TPACKET_V3: Das ist der moderne Ringpuffer im Linux-Kernel, über den libpcap Pakete in Blöcken statt einzeln abholt. Deshalb ist das Mitschneiden heute deutlich ressourcenschonender als in der tcpdump-Zeit der 2000er.

ZweckDebian 13 (Trixie)CachyOS / Archroot nötig?
Paket-Mitschnitttcpdump 4.99.5-2tcpdump 4.99.6-1CAP_NET_RAW
Auswertung von pcap-Dateientshark 4.4.18-0+deb13u1wireshark-cli 4.7.3-1nein (nur Lesen)
Live-Traffic pro Verbindungiftop 1.0~pre4-9iftop 1.0pre4-6CAP_NET_RAW
Traffic pro Prozessnethogs 0.8.8-1nethogs 0.8.8-2CAP_NET_RAW
Balken-Diagramm in der Konsolenload, bmonnload 0.7.4-9, bmon 4.0-5nein (liest Zähler)
Verlaufsstatistik (Datenbank)vnstat 2.13-1vnstat 2.13-2Service als root
Systemstatistik über Zeitsysstat (u. a. sar)sysstat 12.8.0-1Timer als root
Analyse von Netflow-Datennfdumpnicht in den offiziellen Repos (AUR)nein
Ein Befehl für alles: sudo pacman -S tcpdump iftop nethogs nload bmon vnstat iptraf-ng mtr termshark bandwhich ngrep tcpflow darkstat conntrack-tools sysstat iperf3 – bzw. dieselbe Liste unter Debian mit apt install. Für die Auswertung von Mitschnitten reicht tshark (Arch: wireshark-cli), ein grafisches Wireshark braucht man auf dem Server nicht.

Rechte: CAP_NET_RAW statt root

Der Rohzugriff auf das Interface ist eine Capability: CAP_NET_RAW. Ohne sie passiert genau das – ein Mitschnitt als normaler Benutzer scheitert mit einer sehr klaren Meldung:

tcpdump -nn -i enp17s0 -c 1

tcpdump: enp17s0: You don't have permission to perform this capture on that device
(Attempt to create packet socket failed - CAP_NET_RAW may be required)

Dasselbe gilt für iftop, das ebenfalls libpcap benutzt:

iftop -t -s 3

interface: enp17s0
IP address is: 192.168.178.25
MAC address is: 30:56:0f:42:50:2d
pcap_open_live(enp17s0): enp17s0: You don't have permission to perform this capture
on that device (Attempt to create packet socket failed - CAP_NET_RAW may be required)

Es gibt drei saubere Wege, das zu lösen – mit unterschiedlichen Konsequenzen:

WegBefehlVorteilRisiko
Einmalig als rootsudo tcpdump -i any -c 20Nichts zu ändern, ideal für die DiagnoseKeines – solange du nichts dauerhaft laufen lässt
Capability am Binarysudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdumpAuch andere Administratoren dürfen mitschneidenJeder lokale Nutzer darf den gesamten Netzwerkverkehr lesen
Privilegien abgebensudo tcpdump -Z tcpdump -w /var/log/tcpdump/cap.pcapPcap-Dateien gehören nicht root, sondern tcpdumpZielverzeichnis muss dem Benutzer gehören

setcap und getcap sind auf CachyOS vorhanden; getcap ist der schnellste Check, ob ein Binary die Capability trägt:

sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump
getcap /usr/bin/tcpdump
/usr/bin/tcpdump cap_net_admin,cap_net_raw=eip
Zwei Fallen bei setcap: Erstens überschreibt jedes Paket-Update die Datei – die Capability ist danach weg und muss neu gesetzt werden (das merkt man meist erst im Notfall). Zweitens ist ein Binary mit Rohzugriff ein lohnendes Ziel: wer es manipulieren kann, liest jeden Verkehr mit. Deshalb ist die Variante mit sudo oder einer systemd-Unit mit AmbientCapabilities= für einen Server die bessere Wahl.

-Z (ausführlich --relinquish-privileges=user) greift genau dann: tcpdump startet als root, öffnet das Capture-Gerät, wechselt die Benutzerkennung – und öffnet danach erst die Ausgabedateien. So kommen Mitschnitte mit den Rechten des angegebenen Nutzers auf die Platte, während das Öffnen des Interfaces weiterhin privilegiert passiert.

Die erste Aufnahme

Vor dem Filter kommt die Schnittstelle. -D listet sie auf – auf einem Docker-Host ist die Liste länger als erwartet, weil auch die Bridges und die virtuellen Interfaces der Container auftauchen:

tcpdump -D

1.enp17s0 [Up, Running, Connected]
9.any (Pseudo-device that captures on all interfaces) [Up, Running]
10.lo [Up, Running, Loopback]
12.docker0 [Up, Disconnected]
13.wlan0 [Wireless, Not associated]
16.nflog (Linux netfilter log (NFLOG) interface) [none]
17.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none]
18.dbus-system (D-Bus system bus) [none]

Ein Mitschnitt startet man nie ohne Begrenzung. Die Grundform für die Diagnose ist immer dieselbe: Interface, keine Namensauflösung, ein Zähler, ein Filter.

# 20 Pakete auf allen Interfaces, ohne DNS-Lookups, ohne Byte-Grenze
sudo tcpdump -nn -i any -c 20

# Nur Loopback, mit Link-Layer-Kopf (MAC-Adressen)
sudo tcpdump -nn -e -i lo -c 10

# Direkt in eine Datei schreiben (später mit Wireshark & Co. öffnen)
sudo tcpdump -nn -i any -s 128 -w /tmp/mitschnitt.pcap
OptionWirkungWann im Alltag
-i anyAlle Interfaces auf einmal (Pseudogerät)Wenn unklar ist, über welches Interface der Verkehr läuft
-nnKeine Auflösung von Adressen und PortnamenImmer – Lookups kosten Zeit und verfälschen den Mitschnitt
-c 100Nach 100 passenden Paketen beendenImmer, sonst läuft es endlos
-eLink-Layer-Kopf ausgeben (MAC-Adressen)Bei ARP-, VLAN- und Switch-Fragen
-A / -XNutzlast als ASCII / als Hex + ASCIIHTTP-Debugging, DNS-Fragen lesen
-SAbsolute Sequenznummern statt relativerWenn du Pakete über mehrere Mitschnitte vergleichen willst
-qKurze Ausgabe (kein Detail-Header)Bei hoher Paketrate oder wenn nur der Verlauf zählt
-s 128Snaplen: nur die ersten 128 Byte sichernFür lange Mitschnitte: Header reichen meist (Default ist 262144)
-l / -UZeilen- bzw. paketgepufferte AusgabeBei | grep, | tee oder in einem systemd-Journal
Beispielausgaben in diesem Artikel stammen aus einem hier erzeugten Testmitschnitt (neun Pakete: DNS-Anfrage und -Antwort, TLS-Handshake auf Port 443, eine HTTP-Anfrage im Klartext und ein ICMP-Echo) sowie aus dem Lesen und Schreiben von pcap-Dateien. Was das bedeutet – und was hier nicht getestet werden konnte – steht am Ende im Abschnitt Was hier nicht getestet wurde.

Ausgaben lesen

Ein Mitschnitt ohne Filter, aber mit -nn, sieht so aus:

tcpdump -nn -r test.pcap

22:26:40.000400 IP 192.168.178.25.41234 > 9.9.9.9.53: 6699+ A? huuu.biz. (26)
22:26:40.018400 IP 9.9.9.9.53 > 192.168.178.25.41234: 6699 1/0/0 A 203.0.113.7 (42)
22:26:40.020400 IP 192.168.178.25.52344 > 203.0.113.7.443: Flags [S], seq 1000, win 64240, length 0
22:26:40.029400 IP 203.0.113.7.443 > 192.168.178.25.52344: Flags [S.], seq 5000, ack 1001, win 64240, length 0
22:26:40.030400 IP 192.168.178.25.52344 > 203.0.113.7.443: Flags [.], ack 1, win 64240, length 0
22:26:40.033400 IP 192.168.178.25.52344 > 203.0.113.7.443: Flags [P.], seq 1:99, ack 1, win 64240, length 98
22:26:40.038400 IP 192.168.178.25 > 1.1.1.1: ICMP echo request, id 66, seq 1, length 28
22:26:40.049400 IP 1.1.1.1 > 192.168.178.25: ICMP echo reply, id 66, seq 1, length 28
22:26:40.053400 IP 192.168.178.25.60122 > 192.168.178.10.22: Flags [S], seq 2000, win 64240, length 0
Zeichen / FeldBedeutung
Zeitstempel 22:26:40.033400Erfassungszeit im Kernel, Mikrosekunden – mit -tttt kommt das Datum dazu
> und <Richtung: senden bzw. empfangen (bezogen auf den mitschneitenden Host)
[S]SYN – Verbindungsaufbau
[S.]SYN + ACK – die Gegenseite antwortet
[.]Reines ACK ohne Daten
[P.]Push + ACK: dieses Paket trägt Nutzdaten
[F.] / [R]Verbindungsabbau (FIN) bzw. Abbruch (RST)
seq 1:99, length 9898 Byte Nutzdaten; Sequenznummern sind ohne -S relativ zum Beginn der Verbindung
6699+ A? huuu.biz. (26)DNS: Transaktions-ID 6699, + = Rekursion erwünscht, A? = Frage nach einem A-Record
ICMP echo requestPing in Richtung Ziel; echo reply ist die Antwort

Wer absolute Sequenznummern braucht, hängt -S an – dann steht in derselben Zeile seq 1001:1099, ack 5001 statt seq 1:99, ack 1. Mit -e kommt der Link-Layer-Kopf davor, inklusive MAC-Adressen und Ethertype:

tcpdump -nn -e -tttt -r test.pcap

2025-09-20 22:26:40.020400 30:56:0f:42:50:2d > a8:bb:50:c1:d2:e3, ethertype IPv4 (0x0800),
length 54: 192.168.178.25.52344 > 203.0.113.7.443: Flags [S], seq 1000, win 64240, length 0

Und wenn Nutzdaten wirklich lesbar sein sollen (HTTP im Klartext), ist -A die Abkürzung, -X die vollständige Variante mit Hexdump:

tcpdump -nn -A -r test.pcap 'tcp port 443 and tcp[13] & 8 != 0'

22:26:40.033400 IP 192.168.178.25.52344 > 203.0.113.7.443: Flags [P.], seq 1001:1099,
ack 5001, win 64240, length 98
E....4@.@.yp......q..x..........P.......GET /artikel-tcpdump-monitoring HTTP/1.1
Host: huuu.biz
User-Agent: curl/8.21.0
Accept: */*

Filter schreiben (BPF)

Filter sind der wichtigste Teil: Sie entscheiden, ob der Kernel ein Paket überhaupt nach oben kopiert. Die Bausteine sind wenige – und sie lassen sich mit and, or, not und Klammern beliebig kombinieren.

BausteinBedeutungBeispielErgebnis im Testmitschnitt
hostQuelle oder Ziel ist diese Adresse'host 9.9.9.9'Anfrage und Antwort des DNS
src / dstNur eine Richtung'src 9.9.9.9 and udp'Eine Zeile – nur die DNS-Antwort
netGanzes Netz, mit CIDR'net 192.168.178.0/24 and icmp'Echo-Request und Echo-Reply
portQuell- oder Zielport'tcp port 443'Vier Pakete des TLS-Handshakes
portrangePortbereich'portrange 40000-65535'Alle Pakete mit hohen Quellports
greater / lessPaketlänge in Byte'greater 100'Nur das Paket mit 98 Byte Nutzlast
ether hostMAC-Adresse (nur mit Link-Layer-Kopf)'ether src 30:56:0f:42:50:2d and tcp'Nur ausgehende TCP-Pakete
tcp[tcpflags]TCP-Flags direkt adressieren'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'Nur die beiden SYN-Pakete
ip6 / icmp6IPv6 bzw. ICMPv6'icmp6 and ip6[40] == 134'Router Advertisements (Typ 134)

Der Handshake-Filter ist der nützlichste von allen, weil er bei jedem Verbindungsproblem die erste Frage beantwortet: Kommt überhaupt ein SYN an – und antwortet jemand? Im Testmitschnitt liefert er exakt und ausschließlich die beiden Verbindungsaufbauten:

tcpdump -nn -r test.pcap 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'

22:26:40.020400 IP 192.168.178.25.52344 > 203.0.113.7.443: Flags [S], seq 1000, win 64240, length 0
22:26:40.053400 IP 192.168.178.25.60122 > 192.168.178.10.22: Flags [S], seq 2000, win 64240, length 0
Ausdrücke immer in einfache Anführungszeichen setzen. Klammern, | und ? gehören der Shell, nicht tcpdump – 'host a and (b or c)' ist richtig, host a and (b or c) scheitert an der Shell. Wer viel filtert, legt den Ausdruck in eine Datei und nutzt -F filter.txt; darin steht pro Zeile ein Ausdruck, leere Zeilen und #-Kommentare sind erlaubt.

Für die Praxis hilft noch ein Trick: die Ausgabe mit awk oder sort weiterverarbeiten, statt sie zu lesen. Wer wissen will, welche Adressen gerade am meisten sprechen, kommt so in einer Zeile zur Antwort:

# Top-Sprecher auf Port 443 (nach 500 Paketen abbrechen)
sudo tcpdump -nn -i any -c 500 'tcp port 443' 2>/dev/null \
  | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head

Was ein Filter wirklich tut

tcpdump kann den kompilierten Filter ausgeben – das ist die beste Erklärung dafür, warum ein Filter schnell ist und wo seine Grenzen liegen:

tcpdump -d 'tcp port 443'

Warning: assuming Ethernet
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2	jf 8
(002) ldb      [20]
(003) jeq      #0x6             jt 4	jf 19
(004) ldh      [54]
(005) jeq      #0x1bb           jt 18	jf 6
(006) ldh      [56]
(007) jeq      #0x1bb           jt 18	jf 19
(008) jeq      #0x800           jt 9	jf 19
(009) ldb      [23]
(010) jeq      #0x6             jt 11	jf 19
(011) ldh      [20]
(012) jset     #0x1fff          jt 19	jf 13
(013) ldxb     4*([14]&0xf)
(014) ldh      [x + 14]
(015) jeq      #0x1bb           jt 18	jf 16
(016) ldh      [x + 16]
(017) jeq      #0x1bb           jt 18	jf 19
(018) ret      #262144
(019) ret      #0

Das lässt sich Zeile für Zeile lesen – und erklärt drei Dinge auf einmal:

ZeileWas passiertKonsequenz für dich
ldh [12]0x86dd / 0x800Ethertype prüfen: IPv6 oder IPv4Ein Filter kann beide Familien enthalten – IPv6 fällt nicht automatisch raus
ldb [20] jeq 0x6Protokollfeld im IP-Kopf: 6 = TCP, 17 = UDPEin IP-Header ist immer Voraussetzung – ARP oder Nicht-IP wird verworfen
ldh [54] / [56]0x1bb446 in Hex = Port 443, erst Quelle, dann Zieltcp port 443 prüft beide Richtungen – deshalb siehst du Request und Response
jset #0x1fff jt 19Fragment-Offset prüfen: Fragmente werden verworfenPortfilter greifen nur bei nicht fragmentierten Paketen – bei IP-Fragmenten siehst du nichts
ldxb 4*([14]&0xf)IP-Header-Länge auslesen (bei Optionen > 20 Byte)Der Filter bleibt korrekt, auch wenn Optionen im IP-Kopf stehen
ret #262144 / ret #0Paket übernehmen (bis 262144 Byte) oder verwerfen262144 ist der Standard-Snaplen – passt zu tcpdump -s

Die Länge dieses Programms ist der Grund, warum ein Filter im Kernel läuft: Der Kernel entscheidet Byte für Byte, ohne ein Paket zu kopieren, das er nicht braucht. Ein komplexer Filter (port 80 or port 443 or port 53) kostet nur wenige zusätzliche Instruktionen – der Unterschied liegt nicht im Filter, sondern in der Menge der Pakete, die er durchlässt.

Ein Tippfehler im Ausdruck wird übrigens klar gemeldet – nichts läuft stillschweigend schief:

tcpdump -nn -r test.pcap 'tcp port'
tcpdump: can't parse filter expression: syntax error
Die wichtigste Regel für Mitschnitte auf Produktivsystemen: Der Filter muss das Problem eingrenzen, nicht das Interface. tcpdump -i any ohne Filter auf einer belebten Leitung erzeugt Plattenlast, CPU-Last und – bei voller Platte – einen Folgeschaden. Immer -c setzen, immer filtern, im Zweifel -s 128.

Mitschneiden mit Rotation

Für längere Mitschnitte schreibt man in Dateien. Schreiben und wieder lesen funktioniert dabei auch kombiniert – praktisch, um einen unübersichtlichen Mitschnitt auf das Wesentliche zu reduzieren:

# aus dem großen Mitschnitt nur den TLS-Verkehr herausfiltern
tcpdump -nn -r test.pcap -w nur-tls.pcap 'tcp and port 443'
# und wieder ansehen
tcpdump -nn -r nur-tls.pcap
OptionWirkungPraxis
-w datei.pcapSchreibt Rohpakete in eine Datei (Standardformat pcap)Immer mit Zeitstempel im Namen oder mit Rotation
-r datei.pcapLiest eine Datei statt zu mitschneidenAuswertung in Ruhe, auch auf einem anderen Rechner
-C 100Neue Datei, sobald die aktuelle 100 MB (100.000.000 Byte) groß istDateinamen bekommen eine laufende Nummer ab 1
-W 12Nur 12 Dateien anlegen, dann von vorne überschreiben (Ringpuffer)Harte Obergrenze gegen volle Platten; Nummern werden mit führenden Nullen sortierbar gemacht
-G 3600Alle 3600 Sekunden rotieren; im Namen darf ein Zeitformat stehenFür „eine Datei pro Stunde“ – -w cap-%Y%m%d-%H%M.pcap
-z gzipNach jeder Rotation das fertige File komprimierenLäuft parallel zum Mitschnitt mit niedriger Priorität
-s 128Nur die ersten 128 Byte je Paket sichernHeader reichen für Adressen, Ports und Flags – spart 90 % der Dateigröße
-B 40964 MB Kernel-Puffer für die Aufnahme (Angabe in KiB)Bei hoher Rate die erste Stellschraube gegen verlorene Pakete
# Ringpuffer: max. 12 Dateien à 100 MB, komprimiert – deckelt den Platz auf der Platte
sudo install -d -o tcpdump -g tcpdump -m 0700 /var/log/tcpdump
sudo tcpdump -i any -s 128 -C 100 -W 12 -z gzip -Z tcpdump \
     -w /var/log/tcpdump/cap.pcap 'not port 22'

# Oder: eine Datei pro Stunde, komprimiert – Aufräumen übernimmt ein Timer
sudo tcpdump -i any -s 128 -G 3600 -z gzip -Z tcpdump \
     -w '/var/log/tcpdump/cap-%Y%m%d-%H%M.pcap' 'udp port 53 or tcp port 853'
Vorsicht bei -G ohne Zeitformat: tcpdump überschreibt dann bei jeder Rotation die vorherige Datei – der Mitschnitt ist nach einer Stunde weg. Das Zeitformat im Dateinamen (%Y%m%d-%H%M) ist nicht Kosmetik, sondern die Bedingung dafür, dass die Rotation etwas aufbewahrt. Bei -C ohne -W läuft die Nummerierung dagegen endlos weiter und die Platte füllt sich.

Mitschnitt als systemd-Dienst

Wer regelmäßig Fehlerbilder festhalten will, startet den Mitschnitt nicht von Hand, sondern als Unit. Auf Debian 13 und CachyOS ist der Ablauf identisch, weil beide systemd benutzen. Der elegante Weg kommt ohne setcap und ohne dauerhaftes root aus: systemd gibt dem Prozess genau eine Capability und wechselt vorher auf einen eigenen Benutzer.

# Benutzer und Verzeichnis
sudo useradd --system --no-create-home --shell /usr/sbin/nologin tcpdump
sudo install -d -o tcpdump -g tcpdump -m 0700 /var/log/tcpdump

# /etc/systemd/system/netcapture.service
[Unit]
Description=tcpdump-Ringmitschnitt (Netzwerkdiagnose)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/tcpdump -i any -s 128 -C 100 -W 12 -z gzip -Z tcpdump \
          -w /var/log/tcpdump/cap.pcap 'not port 22'
User=tcpdump
Group=tcpdump
AmbientCapabilities=CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_RAW
Nice=-5
IOSchedulingClass=idle
Restart=on-failure
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/log/tcpdump

[Install]
WantedBy=multi-user.target
# Aktivieren – auf beiden Distributionen gleich
sudo systemctl daemon-reload
sudo systemctl enable --now netcapture
systemctl status netcapture
journalctl -u netcapture -f

# Platzverbrauch und Dateien prüfen
du -sh /var/log/tcpdump/
ls -lt /var/log/tcpdump/ | head

Die Unit bringt drei Dinge mit, die eine Handstart-Version nicht hat: AmbientCapabilities ersetzt setcap (und übersteht Updates), Restart=on-failure fängt Abstürze ab, und IOSchedulingClass=idle sorgt dafür, dass das Schreiben der pcap-Dateien die Applikation nicht ausbremst. Wichtig ist der Filter im ExecStart: Ohne ihn schreibt der Dienst alles mit, was über das Interface läuft – inklusive SSH-Sitzungen und Passwörtern, die im Klartext übertragen werden.

-z gzip und -Z tcpdump zusammen: Das Komprimieren läuft als Unterprozess mit den Rechten des Benutzers, auf den tcpdump gewechselt ist – das Verzeichnis muss also tcpdump gehören (daher install -d -o tcpdump). Läuft es als root, entstehen root-Dateien im Verzeichnis und der Dienst scheitert nach der ersten Rotation.

Praxisrezepte

Die folgenden Rezepte decken die Fälle ab, die im Serveralltag wirklich auftreten.

FrageBefehlWorauf du achtest
Wer fragt ständig DNS?sudo tcpdump -nn -i any -c 50 'udp port 53'Viele kurze Anfragen ohne Cache-Treffer deuten auf fehlendes DNS-Caching
Kommt ein SYN an – und antwortet der Server?sudo tcpdump -nn -i any 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'Kein SYN = Firewall/Routing; SYN ohne SYN-ACK = Dienst lauscht nicht oder ist überlastet
Ist es ein TLS-Problem oder ein Netzproblem?sudo tcpdump -nn -i any -c 30 'tcp port 443'Handshake bis zum FIN = Netz in Ordnung, Problem liegt in der Anwendung
DHCP-Vergabe hängtsudo tcpdump -nn -i any -e 'port 67 or port 68'DISCOVER ohne OFFER = kein erreichbarer DHCP-Server im Segment
Router Advertisement fehlt (IPv6)sudo tcpdump -nn -i any 'icmp6 and ip6[40] == 134'Ein RA pro 200–600 Sekunden ist normal; Aushungern führt zu SLAAC-Ausfällen
Läuft der WireGuard-Tunnel?sudo tcpdump -nn -i any -c 20 'udp port 51820'Regelmäßige Pakete bekannter Größe; Stille bedeutet NAT-Timeout oder falscher Port
Traffic aus einem Containersudo tcpdump -nn -i br-14e365259a6e 'port 8080'Container-Bridges heißen br-<ID>; das -D oben zeigt sie
Wer schreit ausgehend ins Internet?sudo tcpdump -nn -i any -c 200 'tcp and not port 22 and not port 53 and not port 443'Unerwartete Ziele und Ports – der erste Schritt jeder Kompromittierungs-Prüfung

Ein Rezept verdient Hervorhebung, weil es in der Praxis am häufigsten falsch gemacht wird: die Suche nach einem Verbindungsabbruch. Hier ist nicht das SYN interessant, sondern das RST – und wer testet, ob die Firewall zurücksetzt oder verwirft, sieht den Unterschied direkt im Mitschnitt:

# Setzt die Gegenseite zurück (RST) oder schweigt sie (Drop)?
sudo tcpdump -nn -i any -c 50 'tcp port 8080'
# RST sofort nach dem SYN  -> Firewall hat aktiv verworfen (REJECT)
# nichts nach dem SYN      -> Paket wird verworfen (DROP) oder Ziel ist aus
Ports statt Namen: Bei einer Suche nach dem Schuldigen lohnt die Frage „welcher Dienst hört auf diesem Port?“ vor dem Mitschnitt – sudo ss -tulpn beantwortet sie sofort und ohne pcap-Datei.

Monitoring ohne root

Für 90 % aller Fragen braucht es keinen Paketmitschnitt. Diese Werkzeuge gehören zur Grundausstattung und laufen ohne Sonderrechte, weil sie Zähler aus dem Kernel lesen:

WerkzeugWas es zeigtroot nötig?
ss -sZusammenfassung aller Socketsnein
ss -tulpnLauschende Ports inklusive Prozessnein (PID nur für eigene Prozesse)
ss -tinTCP-Interna: RTT, cwnd, Retransmits, RTOnein
ss -oTimer (Keepalive, TIME_WAIT)nein
nstat -azKernel-Statistiken (SNMP-Zähler) für IP, TCP, UDP, ICMPnein
ip -s -s linkInterface-Zähler inklusive Fehlerartennein
ethtool -SZähler direkt aus dem NIC-Treibernein
lnstatFortlaufende Kernel-Statistiken im Sekundentaktnein

Die Übersicht ist die schnellste erste Antwort auf „läuft alles normal?“:

ss -s

Total: 1939
TCP:   74 (estab 28, closed 27, orphaned 0, timewait 1)

Transport Total     IP        IPv6
RAW       1         0         1
UDP       67        36        31
TCP       47        37        10
INET      115       73        42

Die Zeile estab 28 ist die interessante: langsam wachsende oder nie abnehmende closed- und orphaned-Werte deuten auf Anwendungen, die Verbindungen nicht sauber schließen. Für einzelne Verbindungen liefert ss -tin die TCP-Interna – im Testsystem zum Beispiel:

ss -tin state established

cubic wscale:11,10 rto:231 rtt:30.412/0.094 ato:43 mss:1368 pmtu:1420 cwnd:10
bytes_sent:14678 bytes_acked:14679 bytes_received:9472 segs_out:368 segs_in:662
send 3598580bps pacing_rate 7197096bps delivery_rate 693136bps minrtt:29.642

Aus dieser einen Zeile lassen sich drei typische Fehlerbilder ablesen: ein hohes rtt mit kleinem cwnd (Bandbreite wird durch Latenz begrenzt), ein retrans-Feld, das nur erscheint, wenn es Retransmits gab, und ein app_limited-Marker, wenn die Anwendung selbst zu langsam Daten nachschiebt – nicht das Netz.

Die Interface-Zähler und die Kernel-Statistik sind das zweite Standbein. Die folgende Ausgabe stammt von einem Rechner, der seit dem letzten Start 1,23 GB empfangen hat – mit 3528 Verwerfungen, ein Wert, den man im Auge behalten sollte:

ip -s -s link show enp17s0

2: enp17s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
    RX:  bytes packets errors dropped  missed   mcast
    1226845829  896593      0    3362       0    2301
    TX:  bytes packets errors dropped carrier collsns
     138298598  386284      0       0       0       0

ethtool -S enp17s0 | head -5
NIC statistics:
     tx_packets: 386373
     rx_packets: 896593
     tx_errors: 0
     rx_errors: 0
FeldBedeutungWann kritisch
errorsFehlerhafte Frames (CRC, Länge, Rahmen)Steigende Werte deuten auf Kabel, Port oder Duplex-Problem
droppedVerworfen, weil kein Speicher frei warBei hoher Last normal in kleinen Zahlen – dauerhaft steigend heißt: Puffer sind zu klein
missedDer Treiber hat Pakete verloren, bevor der Kernel sie sahImmer kritisch: hier leidet die Netzqualität, nicht nur die Statistik
collsnsKollisionen (bei modernen Vollduplex-Links fast immer 0)Werte > 0 bei Vollduplex deuten auf Hardware oder Halbduplex-Zwang

Für die schnelle Frage „was passiert gerade auf Protokollebene?“ ist nstat -az der beste Einstieg – es zeigt absolute Zähler aus dem Kernel, ohne einen einzigen Paketmitschnitt:

nstat -az | head -12

IpInReceives                    1476152            0.0
IpInHdrErrors                   0                  0.0
IpInAddrErrors                  2                  0.0
IpForwDatagrams                 592041             0.0
IpInDiscards                    0                  0.0
IpInDelivers                    882596             0.0
IpOutRequests                   478462             0.0
IpOutNoRoutes                   0                  0.0
Die Kernel-Zähler lügen nicht, aber sie sagen nicht, wer. Wenn ein Zähler auffällt (IpInHdrErrors, IpOutNoRoutes, steigende dropped), ist das der Anlass für einen gezielten Mitschnitt – nicht der Ersatz dafür.

Interaktive Werkzeuge

Wenn man vor dem Terminal sitzt und „einfach mal sehen“ will, sind die Live-Werkzeuge schneller als jeder Mitschnitt. Sie alle brauchen außer nload und bmon die CAP_NET_RAW-Rechte – also ein sudo beim Start.

WerkzeugZeigtBesonderheit
iftopVerbindungen live, sortiert nach BandbreiteDer Klassiker für „wer ist gerade laut“ – mit -t -s 5 auch für Skripte
nethogsBandbreite pro ProzessAntwort auf „welches Programm zieht Daten“ – ohne PID-Sucherei
bandwhichBandbreite pro Prozess und VerbindungModerne Rust-Alternative, liest zusätzlich DNS-Namen mit
nloadEin- und Ausgang als BalkenBraucht keine Sonderrechte – liest /proc/net/dev
bmonGrafische Kurven pro InterfaceIdeal für einen Terminal-Tab auf dem Server
iptraf-ngMenüführung mit Statistik, Ports, PaketgrößenSehr viele Ansichten, dafür gewöhnungsbedürftige Bedienung
termsharkWireshark-Oberfläche im TerminalAuswertung großer pcap-Dateien ohne X11
# Debian 13
sudo apt install iftop nethogs nload bmon iptraf-ng termshark bandwhich

# CachyOS / Arch
sudo pacman -S iftop nethogs nload bmon iptraf-ng termshark bandwhich

# Loslegen (iftop und nethogs brauchen die Capability)
sudo iftop -i enp17s0
sudo nethogs enp17s0
nload enp17s0
Der schnellste Weg zur Antwort „wer zieht Bandbreite?“ ist sudo nethogs oder bandwhich. Beide zeigen den Prozess, während iftop nur Adressen kennt. Für „warum ist die Leitung voll, obwohl niemand etwas tut“ bleiben nur Mitschnitt und ss -tin.

Verlauf und Auswertung

Mitschnitte sind Momentaufnahmen. Sobald die Frage „war das gestern auch schon so?“ lautet, braucht man Verlaufsdaten – und die liefern andere Werkzeuge, weil sie klein und dauerhaft mitschreiben:

WerkzeugDatenhaltungTypische Frage
vnstatKompakte eigene Datenbank, Systemd-Service vnstatWie viel habe ich diesen Monat übertragen – und wann war der Peak?
sysstat (sar)Binärdateien unter /var/log/sysstat/, Timer sysstat-collectWie war die Netzlast gestern um 3 Uhr morgens?
darkstatEigene kleine Datenbank + Web-OberflächeWelche Hosts reden überhaupt mit meinem Server?
tsharkKeine – liest pcap und rechnetWelche TCP-Verbindung hatte die meisten Retransmits?
NetdataEigene Zeitreihen-DatenbankLive-Dashboards für Interface, Sockets und Dienste (siehe unseren Netdata-Artikel)
# Debian 13
sudo apt install vnstat sysstat darkstat

# CachyOS / Arch
sudo pacman -S vnstat sysstat darkstat

# vnstat: Nutzung pro Stunde, Tag und Monat
sudo systemctl enable --now vnstat
vnstat -h          # Stunden
vnstat -d          # Tage
vnstat -m          # Monate
vnstat --live      # Live-Anzeige im Sekundentakt

Für die Auswertung eines Mitschnitts ist tshark das Werkzeug der Wahl, weil es dieselbe Bibliothek benutzt wie Wireshark, aber skriptbar ist:

# Verkehrsaufkommen pro Sekunde
tshark -r /var/log/tcpdump/cap.pcap -q -z io,stat,1

# Top-Gesprächspartner (TCP)
tshark -r cap.pcap -q -z conv,tcp

# Nur die DNS-Fragen auflisten
tshark -r cap.pcap -Y 'dns.flags.response == 0' -T fields -e dns.qry.name | sort | uniq -c | sort -rn
Faustregel: Verlaufsfragen beantwortet man aus Zählern (vnstat, sar, Netdata), Detailfragen aus pcap-Dateien (tcpdump, tshark). Wer beides verwechselt, schreibt entweder zu viele Mitschnitte oder sucht in Zählern nach Details, die dort nicht stehen können.

Durchsatz und Latenz messen

„Das Netz ist langsam“ ist eine Vermutung, keine Messung. Zwei Werkzeuge trennen die Ursachen sauber: iperf3 misst reinen Durchsatz zwischen zwei Endpunkten, curl zerlegt den Weg zur Antwort in Abschnitte – DNS, Verbindungsaufbau, TLS, erster Byte.

# iperf3: auf dem Server starten, auf dem Client messen
iperf3 -s
iperf3 -c server.example -t 10          # TCP, 10 Sekunden
iperf3 -c server.example -u -b 500M     # UDP mit 500 Mbit/s (Paketverlust sichtbar)

Die Latenz zerlegt curl mit -w – die folgende Ausgabe stammt von zwei Aufrufen direkt hintereinander. Der Unterschied zeigt, was DNS-Caching wirklich bringt:

curl -o /dev/null -s -w 'dns=%{time_namelookup} connect=%{time_connect} \
tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' https://example.com

dns=0.036961 connect=0.071372 tls=0.111542 ttfb=0.149867 total=0.149913   # erster Aufruf
dns=0.000828 connect=0.045902 tls=0.098911 ttfb=0.152365 total=0.152411   # direkt danach
MesswertWas er misstTypische Ursache eines Ausreißers
time_namelookupDNS-AuflösungKein lokaler Resolver, langsame Nameserver, DNSSEC-Validierung
time_connectTCP-Handshake (bis SYN-ACK)Hohe RTT, Paketverlust, Firewall mit SYN-Proxy
time_appconnectTLS-HandshakeViele Round-Trips, OCSP-Abruf, alte TLS-Versionen ohne Session-Wiederverwendung
time_starttransferBis zum ersten Byte (TTFB)Langsame Anwendung oder Datenbank – das Netz ist hier nicht schuld
time_totalKompletter AustauschÜbertragungsgröße, Bandbreite, Kompression

Für die Wegstrecke zwischen zwei Hosts ist mtr der Klassiker – es kombiniert ping und traceroute über die Zeit und zeigt, an welchem Hop die Werte auseinanderlaufen:

mtr -n -c 20 server.example        # Debian: Paket mtr-tiny
mtr -n -c 20 -T -P 443 server.example   # als TCP-Test, wenn ICMP gefiltert wird
Immer beide Seiten messen: iperf3 und mtr vergleichen die Sicht des Servers und die des Clients. Ein Unterschied zwischen beiden Richtungen ist fast immer ein Hinweis auf asymmetrische Routen oder Verlust auf dem Rückweg.

Fehlerbild → Befehl

SymptomErster BefehlWas du siehst
You don't have permission to perform this capturegetcap $(command -v tcpdump)Fehlende CAP_NET_RAWsudo nutzen oder Capability setzen
can't parse filter expression: syntax errortcpdump -d 'dein filter'Filter kompiliert nicht – meist ein Shell-Problem (Klammern nicht gequotet)
Mitschnitt bleibt leer, obwohl Traffic läufttcpdump -nn -i any -c 5Falsches Interface (z. B. lo statt any) oder Filter zu eng
„N packets dropped by kernel“ beim Beendensudo tcpdump -i any -B 4096 -w datei.pcapKernel-Puffer zu klein – größerer Puffer, kleinerer Snaplen oder engerer Filter
Container-Verkehr fehlt im Mitschnitttcpdump -D | grep br-Traffic läuft über br-… oder veth…, nicht über das physische Interface
TLS-Nutzlast nicht lesbartcpdump -nn -A 'tcp port 443'Nur Handshake-Metadaten – das ist keine Fehlfunktion, sondern der Sinn von TLS
Mitschnitt ist riesig, Auswertung stockttcpdump -nn -s 128 -C 100 -W 12 -w datei.pcapNutzlast fehlt (Absicht), Dateien sind rotiert und begrenzt
Verbindungen hängen nach Sekundenss -tin state establishedRetransmits, wachsende RTO oder app_limited – drei verschiedene Ursachen

Datenschutz und Aufbewahrung

Ein pcap ist kein technisches Artefakt, sondern eine personenbezogene Datensammlung: Es enthält IP-Adressen, Hostnamen, DNS-Anfragen, TLS-Server-Namen (SNI) – und bei unverschlüsselten Protokollen auch Inhalte wie HTTP-Header, Cookies oder E-Mail-Verkehr im Klartext.

MaßnahmeBefehl / EinstellungWarum
Rechte einschränkenchmod 0700 /var/log/tcpdump, Dateien via -Z tcpdumpMitschnitte sind lesbare Kommunikationsdaten
Nutzlast klein halten-s 128Header statt Inhalte – 128 Byte reichen für Adressen, Ports, Flags
Aufbewahrung deckeln-C 100 -W 12 oder -G 3600 plus Aufräum-TimerWas nicht existiert, muss auch nicht gelöscht werden
Zugriff protokollierenauditctl -w /var/log/tcpdump -p rwa (auditd)Nachvollziehbar, wer Mitschnitte gelesen hat
Nur anlassbezogen mitschneidenTimer statt Dauerbetrieb: OnCalendar= bei systemd-TimerDaueraufzeichnung ohne Anlass ist schwer zu rechtfertigen
Fremdverkehr ausschließenFilter auf die eigene IP: 'host 203.0.113.7'Nur die eigene Infrastruktur, nicht der ganze Link
Ein Mitschnitt auf einem Router oder Gateway erfasst den Verkehr Dritter. Wenn der Server als VPN-Endpunkt oder Router arbeitet, landen fremde Kommunikationsinhalte in der Datei. Filter auf host oder net der eigenen Infrastruktur und kurze Aufbewahrung sind hier keine Formalität, sondern die Bedingung dafür, dass die Diagnose verhältnismäßig bleibt.

Was hier nicht getestet wurde

Damit du einschätzen kannst, worauf die Angaben in diesem Artikel beruhen – und worauf nicht:

AngabeStatus
Version, Bibliothek und Optionen von tcpdump 4.99.6Direkt geprüft (--version, --help, Manpage des Pakets)
Filter, BPF-Code, Fehlermeldungen, -r/-w, AusgabeformateDirekt geprüft – an einem eigens erzeugten Testmitschnitt (9 Pakete) sowie durch Kompilieren der Filter mit -d/-dd
ss, nstat, ip -s -s, ethtool -S, curl -wDirekt geprüft – die gezeigten Zahlen stammen vom Testsystem
Rechteproblem und Fehlermeldung (CAP_NET_RAW)Direkt geprüft – Mitschnitt als normaler Benutzer war nicht möglich, ebenso mit iftop
Paketnamen und Versionen für Debian 13 und CachyOSAus den Distributionsquellen geprüft (Paket-Listen und Repository-Metadaten), aber nicht installiert
Eine echte Live-Aufnahme über das NetzwerkNicht geprüft – im Testsystem fehlten root-Rechte; die Beispielausgaben stammen aus pcap-Dateien
Die systemd-Unit aus dem Abschnitt „Mitschnitt als Dienst“Nicht gestartet – sie ist aus der Manpage abgeleitet (Optionen, Capabilities, -Z)
iperf3, mtr, tshark, vnstat, nethogs, darkstatNicht ausgeführt – Befehle und Optionen entsprechen der jeweiligen Dokumentation
Verhalten von -i any im Cooked-Modus (keine MAC-Adressen)Nicht geprüft – die Geräteliste zeigt any als Pseudogerät; MAC-Filter funktionieren dort nur eingeschränkt
Mitschnitt aus ContainernamespacesNicht geprüft – der Docker-Socket war für den Testaccount nicht erreichbar (Gruppe docker fehlt)

Fazit

tcpdump ist kein Monitoring-System, sondern ein Mikroskop. Der Unterschied entscheidet, ob man damit zwei Minuten oder zwei Stunden verbringt: Erst die Zähler (ss, nstat, vnstat, sar) zeigen, dass etwas nicht stimmt – dann zeigt tcpdump, was los ist. Und weil ein guter Filter mehr wert ist als jede Rechenleistung, gehört die Filterfrage vor die Aufnahmefrage.

Die Kurzfassung für den Serveralltag
1. Zähler zuerst: ss -s, ss -tin, nstat -az, ip -s -s link
2. Rechte: sudo oder CAP_NET_RAW per systemd-Unit – nicht setcap und vergessen
3. Mitschnitt immer begrenzen: -nn -i any -c 100 und ein Filter
4. Lange Mitschnitte nur mit Rotation (-C … -W …) und kleiner -s-Grenze
5. Verlauf aus Zählern (vnstat, sar, Netdata), Details aus pcap (tshark)
6. Aufbewahrung definieren: Rechte 0700, harte Obergrenze, kurze Löschfrist
📝
HuuuHosting-Redaktion

Open-Source-Tools für den eigenen Server – getestet, dokumentiert und in der Debian-13-Serie Schritt für Schritt erklärt.