Das Kommandozeilenwerkzeug tcpdump ist ein mächtiges Instrument zur Netzwerkanalyse. Es hat sich als Industriestandard für die Erfassung und Untersuchung von TCP/IP-Paketen etabliert.
Bei der Behebung von Netzwerkproblemen erweist sich tcpdump als äußerst hilfreich. Die erfassten Pakete lassen sich in einer Datei speichern und zu einem späteren Zeitpunkt analysieren. Es ist ratsam, dieses Werkzeug gelegentlich einzusetzen, um die Netzwerkaktivitäten im Auge zu behalten.
Die Struktur der tcpdump-Ausgabe
tcpdump ermöglicht die detaillierte Betrachtung von TCP/IP-Paketheadern. Für jedes erfasste Paket wird eine Zeile ausgegeben. Der Befehl läuft kontinuierlich, bis er durch die Tastenkombination Strg+C beendet wird.
Betrachten wir ein Beispiel einer solchen Ausgabezeile:
20:58:26.765637 IP 10.0.0.50.80 > 10.0.0.1.53181: Flags [F.], seq 1, ack 2, win 453, options [nop,nop,TS val 3822939 ecr 249100129], length 0
Jede dieser Zeilen enthält folgende Informationen:
- Einen Unix-Zeitstempel (20:58:26.765637).
- Das verwendete Protokoll (IP).
- Die Quell-IP-Adresse oder den Hostnamen mit der zugehörigen Portnummer (10.0.0.50.80).
- Die Ziel-IP-Adresse oder den Hostnamen mit der dazugehörigen Portnummer (10.0.0.1.53181).
- TCP-Flags (Flags [F.]). Diese zeigen den Verbindungsstatus an. Mehrere Flags können gleichzeitig gesetzt sein, wie im Beispiel [F.] für FIN-ACK. Folgende Werte sind möglich:
- S – SYN: Der erste Schritt beim Verbindungsaufbau.
- F – FIN: Verbindungsabbruch.
- . – ACK: Bestätigung für erfolgreich empfangenes Paket.
- P – PUSH: Aufforderung an den Empfänger, Pakete sofort zu verarbeiten und nicht zu puffern.
- R – RST: Sofortiger Abbruch der Kommunikation.
- Die Sequenznummer der Daten im Paket (seq 1).
- Die Bestätigungsnummer (ack 2).
- Die Fenstergröße (win 453), welche die Anzahl der verfügbaren Bytes im Empfangspuffer angibt, gefolgt von den TCP-Optionen.
- Die Länge der Datennutzlast (length 0).
Installation von tcpdump
Auf Debian-basierten Systemen wird tcpdump über den Paketmanager APT installiert:
# apt install tcpdump -y
Auf Systemen, die auf RPM basieren, erfolgt die Installation mittels YUM:
# yum install tcpdump -y
Bei RHEL 8 ist DNF der bevorzugte Paketmanager:
# dnf install tcpdump -y
Befehlsoptionen von tcpdump
Für die Ausführung von tcpdump sind Root-Rechte erforderlich. Das Tool bietet eine Vielzahl von Optionen und Filtern. Wird tcpdump ohne spezifische Optionen gestartet, werden sämtliche Pakete der Standardnetzwerkschnittstelle erfasst.
Um die Liste der verfügbaren Netzwerkschnittstellen zu erhalten, auf denen tcpdump Pakete erfassen kann, verwenden Sie:
# tcpdump -D
Oder:
# Tcpdump --list-interfaces
1.eth0 2.nflog (Linux netfilter log (NFLOG) interface) 3.nfqueue (Linux netfilter queue (NFQUEUE) interface) 4.eth1 5.any (Pseudo-device that captures on all interfaces) 6.lo [Loopback]
Dies ist besonders hilfreich auf Systemen, die keinen separaten Befehl zur Auflistung von Schnittstellen bereitstellen.
Die Option `-i` in Verbindung mit dem Schnittstellennamen ermöglicht die Erfassung von Paketen einer bestimmten Schnittstelle. Ohne diese Angabe verwendet tcpdump die erste gefundene Netzwerkschnittstelle.
# tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes 01:06:09.278817 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 1, length 64 01:06:09.279374 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 4761, seq 1, length 64 01:06:10.281142 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 2, length 64
Das Flag `-v` erhöht den Detailgrad der angezeigten Informationen, `-vv` liefert sogar noch detailliertere Ausgaben.
Standardmäßig löst tcpdump IP-Adressen zu Hostnamen auf und verwendet Dienstnamen anstelle von Portnummern. Um diese Namensauflösung zu deaktivieren, verwenden Sie die Option `-n`.
# tcpdump -n
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100 04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0 04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36 04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0 04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100
Um nur eine bestimmte Anzahl von Zeilen zu erfassen, beispielsweise 5, verwenden Sie das Flag `-c`:
#tcpdump -c 5
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100 04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0 04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36 04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0 04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100 5 packets captured
Standardmäßig verwendet tcpdump Unix-Zeitstempel. Um menschenlesbare Zeitstempel zu verwenden, nutzen Sie:
# tcpdump -tttt
2020-07-06 04:30:12.203638 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186734102:2186734138, ack 204107103, win 37232, length 36 2020-07-06 04:30:12.203910 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0 2020-07-06 04:30:12.204292 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 36:72, ack 1, win 37232, length 36 2020-07-06 04:30:12.204524 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0 2020-07-06 04:30:12.204658 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 72:108, ack 1, win 37232, length 36
Filterausdrücke in tcpdump
Filterausdrücke ermöglichen die Auswahl bestimmter Paketheader zur Anzeige. Werden keine Filter angewendet, werden sämtliche Paketheader ausgegeben. Übliche Filter sind `port`, `host`, `src`, `dst`, `tcp`, `udp` und `icmp`.
Portfilter
Um Pakete zu erfassen, die an einem bestimmten Port ankommen, verwenden Sie den Portfilter:
# Tcpdump -i eth1 -c 5 port 80
23:54:24.978612 IP 10.0.0.1.53971 > 10.0.0.50.80: Flags [SEW], seq 53967733, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0 23:54:24.978650 IP 10.0.0.50.80 > 10.0.0.1.53971: Flags [S.E], seq 996967790, ack 53967734, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0 23:54:24.978699 IP 10.0.0.1.53972 > 10.0.0.50.80: Flags [SEW], seq 226341105, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0 23:54:24.978711 IP 10.0.0.50.80 > 10.0.0.1.53972: Flags [S.E], seq 1363851389, ack 226341106, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0
Hostfilter
So erfassen Sie alle Pakete, die an oder von einem Host mit der IP-Adresse 10.0.2.15 gesendet werden:
# tcpdump host 10.0.2.15
03:48:06.087509 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 3862934963:3862934999, ack 65355639, win 37232, length 36 03:48:06.087806 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0 03:48:06.088087 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 36:72, ack 1, win 37232, length 36 03:48:06.088274 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0 03:48:06.088440 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 72:108, ack 1, win 37232, length 36
Um beispielsweise ICMP-Pakete auf der Schnittstelle `eth1` zu erfassen:
# tcpdump -i eth1 icmp
04:03:47.408545 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 75, length 64 04:03:47.408999 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 75, length 64 04:03:48.408697 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 76, length 64 04:03:48.409208 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 76, length 64 04:03:49.411287 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 77, length 64
Kombination von Filterausdrücken
Filterausdrücke lassen sich mit den Operatoren AND, OR und NOT kombinieren, um spezifischere Pakete zu erfassen.
Pakete von einer bestimmten IP, die für einen bestimmten Port bestimmt sind:
# tcpdump -n -i eth1 src 10.0.0.1 and dst port 80
00:18:17.155066 IP 10.0.0.1.54222 > 10.0.0.50.80: Flags [F.], seq 500773341, ack 2116767648, win 4117, options [nop,nop,TS val 257786173 ecr 5979014], length 0 00:18:17.155104 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [S], seq 904045691, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 257786173 ecr 0,sackOK,eol], length 0 00:18:17.157337 IP 10.0.0.1.54221 > 10.0.0.50.80: Flags [P.], seq 4282813257:4282813756, ack 1348066220, win 4111, options [nop,nop,TS val 257786174 ecr 5979015], length 499: HTTP: GET / HTTP/1.1 00:18:17.157366 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [.], ack 1306947508, win 4117, options [nop,nop,TS val 257786174 ecr 5983566], length 0
Um alle Pakete außer ICMP zu erfassen, verwenden Sie den NOT-Operator:
# tcpdump -i eth1 not icmp
Paket-Header in einer Datei speichern
Die Ausgabe von tcpdump kann schnell am Bildschirm vorbeiscrollen. Daher können Sie die Paketheader mit der Option `-w` in einer Datei speichern. Diese Dateien verwenden das pcap-Format und haben die Dateiendung .pcap.
PCAP steht für Packet Capture. Der folgende Befehl speichert 10 Zeilen der Ausgabe von eth1 in der Datei `icmp.pcap`.
# tcpdump -i eth1 -c 10 -w icmp.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes 10 packets captured 10 packets received by filter 0 packets dropped by kernel
Diese Datei kann mit dem Flag `-r` wieder eingelesen werden:
tcpdump -r icmp.pcap
reading from file icmp.pcap, link-type EN10MB (Ethernet) 05:33:20.852732 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 33, length 64 05:33:20.853245 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 33, length 64 05:33:21.852586 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 34, length 64 05:33:21.853104 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 34, length 64 05:33:22.852615 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 35, length 64
Anzeige von Paketdetails
Bisher wurden nur die Paketheader betrachtet. Um den Paketinhalt anzuzeigen, verwenden Sie die Option `-A`. Dies gibt den Paketinhalt als ASCII-Zeichenkette aus, was bei der Fehlersuche hilfreich ist. Das Flag `-X` kann verwendet werden, um die Ausgabe in hexadezimaler Form zu erhalten. Bei verschlüsselten Verbindungen ist das möglicherweise nicht sehr hilfreich.
# tcpdump -c10 -i eth1 -n -A port 80
23:35:53.109306 IP 10.0.0.1.53916 > 10.0.0.50.80: Flags [P.], seq 2366590408:2366590907, ack 175457677, win 4111, options [nop,nop,TS val 255253117 ecr 5344866], length 499: HTTP: GET / HTTP/1.1 E..'[email protected]@.%. ... ..2...P..M. uE............ .6.}.Q.bGET / HTTP/1.1 Host: 10.0.0.50 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 If-Modified-Since: Tue, 04 Mar 2014 11:46:45 GMT
Fazit
tcpdump ist einfach einzurichten. Sobald Sie die Ausgaben, verschiedenen Optionen und Filter verstanden haben, können Sie es effektiv zur Behebung von Netzwerkproblemen und zur Sicherung Ihres Netzwerks einsetzen.