En djupdykning i tcpdump: Nätverksanalys i kommandoraden
tcpdump är ett kraftfullt verktyg för nätverkssniffning som körs via kommandoraden. Det har blivit en standardmetod för att avlyssna och granska datapaket enligt TCP/IP-protokollet.
Denna applikation är ovärderlig vid felsökning av nätverksproblem. Insamlade paket kan lagras i en fil för efterföljande analys. Det är en god idé att använda detta verktyg regelbundet för att övervaka nätverkstrafiken och upptäcka potentiella problem i tid.
Förstå tcpdumps output
tcpdump ger dig möjlighet att studera huvuddelarna av TCP/IP-paketen. För varje avlyssnat paket visas en rad information. Programmet fortsätter tills du manuellt stoppar det med kommandot Ctrl+C.
Låt oss undersöka ett exempel på en typisk utmatningsrad:
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
Varje utskriftsrad inkluderar följande detaljer:
- Tidsstämpel (Unix-format): (20:58:26.765637)
- Protokoll: (IP)
- Källans IP-adress eller värdnamn samt portnummer (10.0.0.50.80)
- Destinationens IP-adress eller värdnamn och portnummer (10.0.0.1.53181)
- TCP-flaggor (Flags [F.]). Dessa indikerar anslutningens status. Det kan finnas flera flaggor samtidigt, i detta exempel [F.] för FIN-ACK. Möjliga flaggvärden inkluderar:
- S – SYN. Första steget i att upprätta en anslutning.
- F – FIN. Avslutning av en anslutning.
- . – ACK. Bekräftelse att ett paket har tagits emot.
- P – PUSH. Instruerar mottagaren att behandla paketet omedelbart, istället för att lägga det i buffert.
- R – RST. Avbryter kommunikationen.
- Sekvensnummer för datan i paketet (seq 1).
- Kvittensnummer (ack 2).
- Fönsterstorlek (win 453). Indikerar antalet byte som finns tillgängliga i mottagarens buffert. Följs av TCP-alternativ.
- Längd på nyttolasten (length 0).
Installationsanvisningar
På Debianbaserade Linux-distributioner installeras tcpdump med hjälp av APT-pakethanteraren:
# apt install tcpdump -y
På RPM-baserade system som Fedora och CentOS, installeras verktyget med YUM:
# yum install tcpdump -y
Om du använder RHEL 8 eller senare, använd DNF:
# dnf install tcpdump -y
Användbara kommandoalternativ för tcpdump
För att använda tcpdump krävs root-behörighet. Verktyget har många alternativ och filter. Om du kör tcpdump utan argument kommer det att spela in alla paket som passerar genom standardnätverksgränssnittet.
För att visa en lista över tillgängliga nätverksgränssnitt där tcpdump kan avlyssna trafik, använd följande:
# tcpdump -D
Alternativt:
# 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]
Detta är särskilt användbart på system som saknar andra kommandon för att lista nätverksgränssnitt.
För att avlyssna trafik på ett specifikt gränssnitt, ange -i flaggan följt av gränssnittets namn. Om du inte anger -i, kommer tcpdump att använda det första tillgängliga nätverksgränssnittet.
# 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
Flaggan -v ökar detaljnivån i utskriften, medan -vv ger ännu mer detaljerad information.
Som standard försöker tcpdump översätta IP-adresser till värdnamn och portnummer till tjänstnamn. Om DNS inte fungerar, eller om du inte vill att tcpdump ska utföra namnuppslagningar, använd alternativet -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
För att endast registrera ett visst antal paket, t.ex. 5 stycken, använd flaggan -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
Standardutskriften av tcpdump visar Unix-tidsstämplar. För att få en mänskligt läsbar tidsstämpel använd flaggan -tttt:
# 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
Använda filter i tcpdump
Filteruttryck används för att specificera vilka pakethuvuden som ska visas. Om inga filter anges, visas alla pakethuvuden. Vanliga filter är port, host, src, dst, tcp, udp och icmp.
Portfilter
Använd portfilter för att se paket som anländer till en specifik port:
# 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
Värdfilter
För att se paket som kommer till eller lämnar värden med IP-adressen 10.0.2.15, använd följande kommando:
# 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
För att registrera paket av en viss protokolltyp, som till exempel icmp, på gränssnittet eth1:
# 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
Kombinera filteruttryck
Du kan kombinera filteruttryck med hjälp av operatorerna AND, OR och NOT. Detta gör att du kan skapa mer detaljerade filter:
För att se paket från en specifik IP-adress som är avsedda för en viss port:
# 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
För att se alla paket utom ICMP-trafik, använd NOT-operatorn:
# tcpdump -i eth1 not icmp
Spara paketdata till en fil
Eftersom tcpdumps utmatning kan rulla förbi skärmen snabbt, kan du spara datapaket till en fil med flaggan -w. Filerna sparas i pcap-format och har filändelsen .pcap.
PCAP står för ”packet capture”. Följande kommando sparar 10 rader utmatning på eth1-gränssnittet till filen 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
Du kan läsa den sparade filen med flaggan -r:
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
Visa paketdetaljer
Hittills har vi bara sett pakethuvuden. För att se själva datainnehållet, använd alternativet -A. Detta skriver ut paketets data i ASCII-format, vilket är användbart vid nätverksfelsökning. Alternativt kan -X-flaggan användas för att visa datan i hexadecimalt format. Detta kan vara mindre användbart om anslutningen är krypterad.
# 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
Sammanfattning
tcpdump är enkelt att använda, och när du förstår hur utmatningen fungerar, samt de olika flaggorna och filtren, kan verktyget vara mycket användbart för att diagnostisera nätverksproblem och säkra ditt nätverk.