Tips en Trucs 2022

Netwerkproblemen oplossen met tcpdump

Als er één netwerk hulpprogramma is waarmee je veel netwerkproblemen kunt oplossen, dan is het wel het tcpdump programma. Om tcpdump te leren gebruiken, kan je beginnen met enkele eenvoudige opdrachten waardoor je het netwerkverkeer en de tcpdump opties leert begrijpen. Vandaag nemen we een duik in de tcpdump opdracht - waar het voor gebruikt wordt en wat je moet weten. We bekijken ook een simulatie van een netwerk probleemsituatie.

Wat is tcpdump?

Tcpdump werd eind jaren '80 ontwikkeld en is sinds die tijd niet meer weg te denken uit de wereld van netwerk foutopsporing. Het wordt verspreid onder een BSD licentie en is vrij te downloaden en te gebruiken. Het werkt op de meeste *nix besturingssystemen en heeft een geporteerde versie voor Windows. Op het meest basale niveau is tcpdump een programma om netwerkpakketten te vangen om problemen met netwerkconnectiviteit op te lossen. Het is waarschijnlijk het best te vergelijken met Wireshark. Het is echter veel lichter en werkt alleen met de opdrachtregel (voor zover ik weet is er geen GUI beschikbaar).

Tcpdump installeren

Tcpdump installeer je in openSUSE Leap 15.3 met de volgende opdracht:

dany@pindabook:~> sudo zypper install tcpdump
[sudo] wachtwoord voor root: 
Gegevens van opslagruimte laden...
Lezen van geïnstalleerde pakketten...
Pakketafhankelijkheden oplossen...

De volgende 3 NIEUWE pakketten zullen worden geïnstalleerd:
  libsmi libsmi2 tcpdump

3 nieuwe te installeren pakketten.
Totale downloadgrootte: 2,6 MiB. Reeds in de cache: 0 B. Na de bewerking zal aanvullend 17,8 MiB worden gebruikt.
Doorgaan? [j/n/v/...? alle opties tonen] (j): 
pakket libsmi-0.4.8-1.29.x86_64 wordt opgehaald                                                (1/3),   2,1 MiB ( 16,3 MiB uitgepakt)
Ophalen: libsmi-0.4.8-1.29.x86_64.rpm .........................................................................[gereed (805,2 KiB/s)]
pakket libsmi2-0.4.8-1.29.x86_64 wordt opgehaald                                               (2/3), 111,2 KiB (459,5 KiB uitgepakt)
Ophalen: libsmi2-0.4.8-1.29.x86_64.rpm ......................................................................................[gereed]
pakket tcpdump-4.9.2-3.18.1.x86_64 wordt opgehaald                                             (3/3), 396,0 KiB (  1,1 MiB uitgepakt)
Ophalen: tcpdump-4.9.2-3.18.1.x86_64.rpm ....................................................................................[gereed]

Controleren op conflicten tussen bestanden: .................................................................................[gereed]
(1/3) Installeren van: libsmi-0.4.8-1.29.x86_64 .............................................................................[gereed]
(2/3) Installeren van: libsmi2-0.4.8-1.29.x86_64 ............................................................................[gereed]
(3/3) Installeren van: tcpdump-4.9.2-3.18.1.x86_64 ..........................................................................[gereed]

Tcpdump gebruiken

Nu dat we tcpdump klaar hebben voor gebruik, gaan we eens kijken naar de meest elementaire functies. Om te beginnen met het vastleggen van pakketten over een netwerkverbinding, moeten we de beschikbare netwerkverbindingen weergeven. Om dit te doen, gebruiken we:

dany@pindabook:~> sudo tcpdump -D
[sudo] wachtwoord voor root: 
1.eth1 [Up, Running]
2.lo [Up, Running, Loopback]
3.any (Pseudo-device that captures on all interfaces) [Up, Running]
4.wlan1 [Up]
5.bluetooth-monitor (Bluetooth Linux Monitor) [none]
6.nflog (Linux netfilter log (NFLOG) interface) [none]
7.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none]
8.dbus-system (D-Bus system bus) [none]
9.dbus-session (D-Bus session bus) [none]
10.bluetooth0 (Bluetooth adapter number 0) [none]

Deze opdracht is uiterst nuttig in omgevingen waar specifieke netwerkverbindingen worden gebruikt om bepaalde soorten gegevens te verplaatsen. Laten we nu wat pakketten vangen, zodat we de uitvoer kunnen zien en welke informatie we daarmee verzamelen.

dany@pindabook:~> sudo tcpdump -i any
[sudo] wachtwoord voor root: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
15:51:47.455068 ARP, Request who-has tasmota-8BBE4D-7757.lan tell tasmota-8BBE4D-7757.lan, length 46
15:51:47.455617 IP6 fd00:e077:be82:0:1b8c:ee47:71bb:f328.46273 > mymodem.lan.domain: 44640+ PTR? 7.1.168.192.in-addr.arpa. (42)
15:51:47.457547 IP6 mymodem.lan.domain > fd00:e077:be82:0:1b8c:ee47:71bb:f328.46273: 44640* 1/0/0 PTR tasmota-8BBE4D-7757.lan. (79)
15:51:47.457999 IP6 fd00:e077:be82:0:1b8c:ee47:71bb:f328.44206 > mymodem.lan.domain: 43007+ PTR? 8.2.3.f.b.b.1.7.7.4.e.e.c.8.b.1.0.0.0.0.2.8.e.b.7.7.0.e.0.0.d.f.ip6.arpa. (90)
15:51:47.460108 IP6 mymodem.lan.domain > fd00:e077:be82:0:1b8c:ee47:71bb:f328.44206: 43007 NXDomain* 0/0/0 (90)
15:51:47.707672 ARP, Request who-has tasmota-4FDD94-7572.lan tell mymodem.lan, length 46
15:51:47.708023 IP6 fd00:e077:be82:0:1b8c:ee47:71bb:f328.43472 > mymodem.lan.domain: 33118+ PTR? 31.1.168.192.in-addr.arpa. (43)
15:51:47.710127 IP6 mymodem.lan.domain > fd00:e077:be82:0:1b8c:ee47:71bb:f328.43472: 33118* 1/0/0 PTR tasmota-4FDD94-7572.lan. (80)
15:51:47.710551 IP6 fd00:e077:be82:0:1b8c:ee47:71bb:f328.47719 > mymodem.lan.domain: 38814+ PTR? 1.1.168.192.in-addr.arpa. (42)
15:51:47.712558 IP6 mymodem.lan.domain > fd00:e077:be82:0:1b8c:ee47:71bb:f328.47719: 38814* 1/0/0 PTR mymodem.lan. (67)
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Hier gebruiken we de -i (--interface) optie om de netwerkverbinding aan te duiden, eender welke (any), in dit geval, waarop we willen luisteren. Merk op dat tcpdump doorgaat met het vangen van pakketten totdat een interrupt signaal wordt gegeven via Ctrl+c. De andere optie die je kunt gebruiken is de -c optie om het aantal gevangen pakketten te beperken. Deze limiet is naar mijn mening één van de beste manieren om de opdracht te gebruiken, omdat je meestal bezig bent om de connectiviteit te achterhalen (die vrij snel gediagnosticeerd kan worden).

dany@pindabook:~> sudo tcpdump -i any -c 3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
15:54:53.904076 ARP, Request who-has main.lan tell pindabook.lan, length 28
15:54:53.904456 ARP, Reply main.lan is-at a4:bb:6d:48:71:05 (oui Unknown), length 46
15:54:53.904671 IP6 fd00:e077:be82:0:1b8c:ee47:71bb:f328.35821 > mymodem.lan.domain: 1731+ PTR? 24.1.168.192.in-addr.arpa. (43)
3 packets captured
6 packets received by filter
0 packets dropped by kernel

Ik heb nog een snelle tip voor het opsporen van netwerkfouten met tcpdump. Standaard zet het IP adressen en poortnummers om in namen (zie hierboven). In grote omgevingen waar naamgevingsschema's een beetje lastig zijn, kan je het omzetten van IP adressen en poortnummers uitschakelen. Vanuit het perspectief van technische probleemoplossing vind ik dit veel minder verwarrend. Het maakt ook het doorzoeken van de uitvoer een beetje gemakkelijker. We gebruiken de -n optie om naam- en poortresolutie uit te schakelen:

dany@pindabook:~> sudo tcpdump -i any -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
15:56:24.410881 ARP, Request who-has 192.168.1.63 tell 192.168.1.1, length 46
15:56:24.680015 IP 192.168.1.9.46396 > 185.111.204.220.123: NTPv4, Client, length 48
15:56:24.691686 IP 185.111.204.220.123 > 192.168.1.9.46396: NTPv4, Server, length 48
3 packets captured
3 packets received by filter
0 packets dropped by kernel

Andere nuttige filters

Filteren op IP adres: sudo tcpdump host x.x.x.x ....

Filteren op netwerkverbinding: sudo tcpdump -i eth0 ....

Filteren op bron: sudo tcpdump src x.x.x.x ....

Filteren op doel: sudo tcpdump dst x.x.x.x ....

Filteren op protocol: sudo tcpdump icmp ....

tcpdump

Er zijn een groot aantal opties en filters om je vangsten te verfijnen tot alleen het meest bruikbare verkeer. Als je meer info nodig hebt, kijk dan op de man pagina of andere online bronnen.

Simulatie

We gebruiken twee computers met openSUSE Leap 15.3. Op de ene computer (server) blokkeren we tijdelijk het ICMP netwerkverkeer via de firewall met de opdracht:

dany@main:~> sudo firewall-cmd --add-icmp-block-inversion
[sudo] wachtwoord voor root:
success

Op een tweede computer (client) starten we in een aparte terminal een ping opdracht:

dany@pindabook:~> ping main
PING main.lan (192.168.1.24) 56(84) bytes of data.
From main.lan (192.168.1.24) icmp_seq=1 Packet filtered
From main.lan (192.168.1.24) icmp_seq=2 Packet filtered
From main.lan (192.168.1.24) icmp_seq=3 Packet filtered
From main.lan (192.168.1.24) icmp_seq=4 Packet filtered
...

Op diezelfde computer (client) onderzoeken we met tcpdump het netwerkverkeer naar de server in een aparte terminal, dus terwijl de ping opdracht zijn werk doet.

dany@pindabook:~> sudo tcpdump -i eth1 -c 10 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:37:36.759115 STP 802.1d, Config, Flags [none], bridge-id 8000.a4:bb:6d:48:71:05.8001, length 43
16:37:36.976126 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 18, length 64
16:37:36.976752 IP 192.168.1.24 > 192.168.1.9: ICMP host 192.168.1.24 unreachable - admin prohibited filter, length 92
16:37:38.000125 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 19, length 64
16:37:38.000828 IP 192.168.1.24 > 192.168.1.9: ICMP host 192.168.1.24 unreachable - admin prohibited filter, length 92
16:37:38.743140 STP 802.1d, Config, Flags [none], bridge-id 8000.a4:bb:6d:48:71:05.8001, length 43
16:37:39.024132 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 20, length 64
16:37:39.024707 IP 192.168.1.24 > 192.168.1.9: ICMP host 192.168.1.24 unreachable - admin prohibited filter, length 92
16:37:40.048124 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 21, length 64
16:37:40.048902 IP 192.168.1.24 > 192.168.1.9: ICMP host 192.168.1.24 unreachable - admin prohibited filter, length 92
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Je ziet in het bovenstaande netwerkverkeer dat er enkel verzoeken (request) naar de server worden verzonden. Maar er zijn geen antwoorden (reply) te bespeuren. In een echt scenario zou dit wijzen op een probleem op de bestemming, aangezien we duidelijk kunnen zien dat het verkeer wordt verzonden over de broninterface.

Configureren we op de server de firewall terug zodat het ICMP netwerkverkeer niet langer geblokkeerd wordt.

dany@main:~> sudo firewall-cmd --remove-icmp-block-inversion
success

M.a.w. na het oplossen van het probleem bij de bestemming, toont tcpdump het volgende netwerkverkeer:

dany@pindabook:~> sudo tcpdump -i eth1 -c 10 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:40:24.758976 STP 802.1d, Config, Flags [none], bridge-id 8000.a4:bb:6d:48:71:05.8001, length 43
16:40:24.912131 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 182, length 64
16:40:24.912874 IP 192.168.1.24 > 192.168.1.9: ICMP echo reply, id 6, seq 182, length 64
16:40:25.594631 IP6 fe80::3291:8fff:fe12:7f8c > ff02::1:ff66:e730: ICMP6, neighbor solicitation, who has 2a02:a03f:f03e:3000:778d:fcde:8066:e730, length 32
16:40:25.936132 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 183, length 64
16:40:25.936850 IP 192.168.1.24 > 192.168.1.9: ICMP echo reply, id 6, seq 183, length 64
16:40:26.001247 IP6 fe80::3291:8fff:fe12:7f8c.14043 > ff02::15d.14041: UDP, length 48
16:40:26.743132 STP 802.1d, Config, Flags [none], bridge-id 8000.a4:bb:6d:48:71:05.8001, length 43
16:40:26.960127 IP 192.168.1.9 > 192.168.1.24: ICMP echo request, id 6, seq 184, length 64
16:40:26.960797 IP 192.168.1.24 > 192.168.1.9: ICMP echo reply, id 6, seq 184, length 64
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Een nadere blik op de uitvoer toont aan dat het verkeer met succes van de bronserver naar de doelserver wordt verzonden.

Opruimen

Het tcpdump pakket en alle bijhorende bibliotheken die niet langer van nut zijn voor andere pakketten, verwijder je met:

dany@pindabook:~> sudo zypper remove -u tcpdump
[sudo] wachtwoord voor root: 
Lezen van geïnstalleerde pakketten...
Pakketafhankelijkheden oplossen...

De volgende 3 pakketten zullen worden VERWIJDERD:
  libsmi libsmi2 tcpdump

3 te verwijderen pakketten.
Na de bewerking zal 17,8 MiB worden vrijgemaakt.
Doorgaan? [j/n/v/...? alle opties tonen] (j): 
(1/3) Verwijderen van tcpdump-4.9.2-3.18.1.x86_64 ...........................................................................[gereed]
(2/3) Verwijderen van libsmi-0.4.8-1.29.x86_64 ..............................................................................[gereed]
(3/3) Verwijderen van libsmi2-0.4.8-1.29.x86_64 .............................................................................[gereed]