Hur fångas och analyseras nätverkstrafik med tcpdump?

tcpdump är ett fantastiskt kommandoradsverktyg för nätverkssniffning. Det är en industristandard för att fånga och analysera TCP/IP-paket.

Verktyget tcpdump kan vara till stor hjälp när du löser nätverksproblem. Paketen kan sparas i en fil och sedan analyseras. Det är en bra idé att köra det här verktyget då och då för att hålla koll på ditt nätverk.

Hur ser tcpdump-utgången ut?

tcpdump låter dig undersöka rubrikerna för TCP/IP-paketen. Den skriver ut en rad för varje paket, och kommandot fortsätter att köras tills du trycker på Ctrl+C för att avsluta.

Låt oss undersöka en rad från ett exempelutdata:

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 rad inkluderar

  • Unix tidsstämpel (20:58:26.765637)
  • protokoll (IP)
  • källans värdnamn eller IP och portnummer (10.0.0.50.80)
  • destinationsvärdnamn eller IP och portnummer (10.0.0.1.53181)
  • TCP-flaggor (flaggor [F.]). Flaggor indikerar anslutningens tillstånd. Detta kan innehålla mer än ett värde, som i det här exemplet [F.] för FIN-ACK. Detta fält kan ha följande värden:
    • S – SYN. Det första steget för att upprätta anslutningen.
    • F – FIN. Anslutningsavslutning.
    • . – ACK. Bekräftelsepaketet togs emot.
    • P – PUSH. Ber mottagaren att behandla paket istället för att buffra dem.
    • R – RST. Kommunikationen stoppades.
  • Sekvensnummer för data i paketet. (seq 1)
  • Kvittensnummer (ack 2)
  • Fönsterstorlek (vinst 453). Antalet byte tillgängliga i den mottagande bufferten. Detta följs av TCP-alternativ.
  • Längden på datanyttolasten. (längd 0)

Installation

På Debianbaserade distributioner kan tcpdump installeras med APT-kommandot:

# apt install tcpdump -y

På RPM-baserade distributioner kan tcpdump installeras med YUM :

# yum install tcpdump -y

Eller använder DNF om RHEL 8

# dnf install tcpdump -y

tcpdump kommandoalternativ

Du måste vara root för att köra tcpdump. Den innehåller många alternativ och filter. Att köra tcpdump utan några alternativ kommer att fånga alla paket som flödar genom standardgränssnittet.

För att se listan över nätverksgränssnitt som är tillgängliga på systemet och på vilka tcpdump kan fånga paket.

# tcpdump -D

Eller

# 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 inte har ett kommando för att lista gränssnitt.

För att fånga paket som flyter genom ett specifikt gränssnitt, använd flaggan -i med gränssnittsnamnet. Utan -i-gränssnittet kommer tcpdump att plocka upp det första nätverksgränssnittet det stöter på.

# 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

-v-flaggan ökar informationen du ser om paketen, -vv ger dig ännu mer detaljer.

Som standard löser tcpdump IP-adresser till värdnamn och använder även tjänstnamn istället för portnummer. Om DNS är trasigt eller du inte vill att tcpdump ska utföra namnsökningar, 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 bara fånga en uppsättning rader, säg 5, 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

Standardutdata för tcpdump använder Unix-tidsstämplar. Så här fångar du paket med mänskligt läsbar tidsstämpel:

# 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

tcpdump filteruttryck

Filteruttryck väljer vilka paketrubriker som ska visas. Om inga filter används visas alla paketrubriker. Vanligt använda filter är port, host, src, dst, tcp, udp, 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 fånga alla paket som anländer till eller lämnar värden med IP-adressen 10.0.2.15:

# 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 fånga paket av en specifik protokolltyp, till exempel icmp, på eth1-gränssnittet:

# 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 dessa filteruttryck med AND-, OR- och NOT-operatorer. Detta gör att du kan skriva kommandon som kan isolera paket mer exakt:

Paket från en specifik IP och avsedda för en specifik 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 fånga alla paket utom ICMP, använd NOT-operatorn:

# tcpdump -i eth1 not icmp

Sparar pakethuvuden till en fil

Eftersom utdata från tcpdump kan rulla förbi skärmen ganska snabbt, kan du lagra pakethuvuden till en fil med flaggan -w. Filerna för att spara utdata använder pcap-format och har filtillägget .pcap.

PCAP står för packet capture. Följande kommando sparar 10 rader utdata på eth1-gränssnittet till 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 här filen med -r flaggan:

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 paketinnehåll använd -A-alternativet. Detta skriver ut paketinnehållet i ASCII, vilket kan vara till hjälp vid nätverksfelsökning. Även -X-flagga kan användas för att visa utdata i hex-format. Detta kanske inte är till mycket hjälp 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

Slutsats

tcpdump är lätt att ställa in, och när du väl förstår utdata, de olika flaggorna och filtren kan den användas för att lösa nätverksproblem och säkra ditt nätverk.