Letzte Anpassung: 02.2024
- Layoutaktualisierung
Einleitung
Falls eine TCP/IP-Verbindung mal nicht funktioniert, bietet die Firewall einige Möglichkeiten den Fehlern auf die Spur zu kommen. Konkret gibt es drei Level der Analyse, die immer tiefer in das System hinabsteigen. Das oberste Level ist über das Webinterface erreichbar, die unteren Level benötigen eine Textkonsole, entweder über SSH oder lokal am Gerät.
Die Level der Fehleranalyse
Level 1: Livelog
Unter
ist das Livelog zu finden.Das Livelog zeigt neben Applikationsmeldungen auch Meldungen des Paketfilters an. Standardmäßig ist allerdings nur zu sehen, wenn die Default Policy Pakete verwirft, für die es keine passende Firewallregel gibt. Es lässt sich aber für jede Firewall-Regel das Logging konfigurieren, so dass auch ein Eintrag erscheint, wenn diese Regel greift.
Dadurch ergeben sich in der Fehlersuche drei Möglichkeiten:
- Das gesuchte Paket taucht auf und es wird verworfen (DROP)
- Das gesuchte Paket taucht auf und es wird akzeptiert (ACCEPT)
- Das gesuchte Paket taucht nicht auf
Dadurch kann die Fehlerursache lokalisiert werden:
- Wenn ein Paket verworfen wird, fehlt die passende FW-Regel, sie ist nicht korrekt erstellt oder noch nicht wirksam (Regelwerk noch nicht aktualisiert)
- Wenn ein Paket angenommen wird, dann liegt der Fehler vermutlich in Richtung Zielhost.
- Ist kein Paket im Livelog sichtbar, dann kommt vermutlich auch keins an der Firewall an. Der Fehler ist hier vermutlich in Richtung Quellhost zu suchen.
Level 2: CLI
Das CLI (Command Line Interface) stellt die Schnittstelle zum Firewall-Server dar, welche zum einen vom Webinterface genutzt wird, zum anderen auch auf der Konsole zur manuellen Konfiguration der Firewall genutzt werden kann. Für die Fehlersuche bei Verbindungsproblemen ist das CLI allerdings nur von begrenztem Nutzen.
Das CLI kann über das Webinterface oder über eine Textkonsole erreicht werden. Dazu ist ein Benutzer mit Administrationsrechten notwendig.
Level 3: Linux-Shell
Die Linux-Shell greift auf das zugrundeliegende Betriebssystem zurück. Man erhält Zugriff auf viele Systemparameter, die über das Webinterface oder das CLI nicht zugänglich sind - wenn auch zumeist nur lesend. Mit dem Paketsniffer tcpdump steht auf der linux-Shell ein sehr leistungsfähiges Werkzeug zur Trafficanalyse zur Verfügung.
Die Linux-Shell erreicht man ausschließlich mithilfe eines Benutzers der root-Berechtigungen hat.
Tcpdump auf der root-Konsole
Voraussetzungen
Die Voraussetzungen zur Verwendung von tcpdump sind Folgende:
- Ein User „root“ in der Gruppe Administrator
- Ein SSH-Client (z. B. PuTTY) oder eine lokale Konsole auf der Firewall
Parameter zur Steuerung und Filterung
Die Verwendung von tcpdump ohne Parameter würde einfach JEDES tcp/ip-Paket auf der Konsole anzeigen. Es ist also notwendig, durch entsprechende Filterparameter ein Suchmuster vorzugeben.
-i definiert das Interface, an dem ein- oder ausgehende Pakete angezeigt werden sollen.
Beispiel:
tcpdump -i A1
proto definiert die Protokollnummer auf Transportebene.
Beispiele:
tcpdump -i A1 proto 1 zeigt ICMP-Pakete
tcpdump -i A1 proto 6 zeigt TCP-Pakete
tcpdump -i A1 proto 17 zeigt UDP-Pakete
tcpdump -i A1 proto 50 zeigt ESP-Pakete
port definiert tcp- oder udp-ports.
Beispiel:
tcpdump -i A1 port 80
host definiert einen bestimmten Host mit seiner IP als Quelle oder Ziel.
Beispiel:
tcpdump -i A1 host 10.0.0.1
net definiert ein Netzwerk (Quelle oder Ziel)
Beispiel:
tcpdump -i A1 net 10.0.0.0/24
Darüber hinaus lassen sich Filterparameter mit logischen Operatoren verknüpfen. So können folgendermaßen alle ICMP-Pakete für Host 10.0.0.10 angezeigt werden:
tcpdump -i A1 proto 1 and host 10.0.0.10
Weitere Steuerungsparameter sind beispielsweise:
-n verhindert, dass tcpdump versucht, einen reverse lookup auf IP-Adressen zu machen, um Hostnamen anzuzeigen.
-s legt fest, bis zu welcher Länge ein Paket mitgeschnitten wird. Mit dem Wert 0 wird das komplette Paket mitgeschnitten.
-w leitet die Ausgabe in eine Textdatei um. Diese kann dann mit einem Analysetool, z.B. wireshark, weiter untersucht werden. Als Wert wird der Pfad der Textdatei angegeben, z.B. /var/tcpdump.txt
Die Trafficanalyse
In unserem Beispiel haben wir zwei Netzwerke der Zentrale und eines Filialstandortes einer Firma, deren Gateways diese Netze mittels eines IPSec-Tunnels miteinander verbinden. Die Zentrale hat das interne Netzwerk 10.0.0.0/24 und die externe Adresse 198.51.100.75. Die Filiale hat das interne Netzwerk 10.4.0.0/24 und die externe Adresse 198.51.100.4. Der Host 10.0.0.10 versucht, den Host 10.4.0.10 zu erreichen, was aber misslingt.
Initiator-Seite: Intern
Wir beginnen unsere Analyse am internen Interface des Gateways der Zentrale. Dazu melden wir uns per ssh als User „root“ dort an und führen folgendes Kommando aus:
tcpdump -i A1 proto 1 -n
Der Parameter proto 1 bezieht sich auf die Protokollnummer 1 des ICMP-Protokolls auf Transportebene. Alternativ können wir auch nach Paketen suchen, die für das entfernte Subnetz bestimmt sind:
tcpdump -i A1 net 10.4.0.0/24 -n
Versuchen wir jetzt zu pingen, zeigt sich folgendes Ergebnis:
09:59:44.445502 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
09:59:49.847558 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
09:59:54.855574 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
09:59:59.861512 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
Wir sehen das die Anfragen am internen Interface der zentralen Firewall ankommen. Eine Antwort bleibt allerdings aus.
Initiator-Seite: Extern
Zur weiteren Verfolgung muss das ausgehende Interface der zentralen Firewall betrachtet werden. Allerdings ergibt sich hier ein Problem: Da wir an dieser Stelle den Transport der übertragenen Daten nur in verschlüsselter Form betrachten können, bleibt uns das ICMP-Paket im Klartext verborgen - und das sollte auch so sein. Wir können allerdings versuchen, eingehendes Klartext- und ausgehendes verschlüsseltes Paket miteinander in Beziehung zu setzen. Wir starten dazu tcpdump mit folgenden Parametern:
tcpdump -i any proto 1 or proto 50 -n
Wir suchen an einer beliebigen Schnittstelle nach ICMP-Paketen oder nach verschlüsselten Paketen. Das hierzu von IPSec verwendete Protokoll ESP hat auf der Transportebene die Protokollnummer 50. Gibt es mehrere IPSec-Verbindungen auf dem Gateway, kann alternativ auch nach Paketen für das entfernte Subnetz oder das entfernte Gateway gesucht werden:
tcpdump -i any net 10.4.0.0/24 or host 198.51.100.4 -n
Wir erhalten folgendes Ergebnis:
10:21:39.710743 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
10:21:39.710799 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0x9), length 92
10:21:45.056141 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
10:21:45.056235 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0xa), length 92
10:21:50.065278 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
10:21:50.065332 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0xb), length 92
10:21:55.075902 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
10:21:55.075947 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0xc), length 92
Wir sehen vier ICMP Echo Request-Pakete mit aufeinanderfolgenden Sequenznummern, denen jeweils direkt ein ESP-Paket folgt. Diese ESP-Pakete haben ebenfalls aufeinanderfolgende Sequenznummern. Daraus folgt, dass auf Seiten der zentralen Firewall alle Datenpakete für das entfernte Subnetz verschlüsselt und an das entfernte Gateway geschickt werden.
Möglicherweise bekommen wir allerdings folgendes Ergebnis:
10:58:15.436094 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
10:58:15.436127 IP 198.51.100.75 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
10:58:20.810201 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
10:58:20.810230 IP 198.51.100.75 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
10:58:25.820479 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
10:58:25.820533 IP 198.51.100.75 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
10:58:30.830402 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
10:58:30.830470 IP 198.51.100.75 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
Wir sehen jedes Paket zwei Mal, erkennbar an der gleichen Sequenznummer. Die zweite Version des Pakets hat allerdings die IP des externen Interfaces als Quelle. Es erfolgte also ein HideNAT über die externe Schnittstelle. In diesem Falle haben wir wahrscheinlich vergessen, innerhalb der Portfilterregel vom eigenen in das entfernte Subnetz die HideNAT-Ausnahme zu setzen oder die Option „Kein NAT für IPSec-Verbindungen“ in den impliziten Regeln zu aktivieren. Infolgedessen wird das Paket, anstatt verschlüsselt in den IPSec-Tunnel zu gehen, geNATtet und in Richtung Default Gateway geschickt.
Responder-Seite: Extern
Gehen wir davon aus, dass auf dem Gateway der Zentrale alles funktioniert, müssen wir weiter auf dem Gateway der Filiale suchen. Zunächst vergewissern wir uns, dass die verschlüsselten Daten auch an der Gegenstelle ankommen. Das diese von der Zentrale aus abgeschickt werden, heißt noch lange nicht, dass sie auch ankommen! Deshalb führen wir auf der SSH-Konsole auf der Filiale folgendes Kommando aus:
tcpdump -i A0 proto 50 -n
Das Ergebnis ist folgende Ausgabe:
11:24:55.833742 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0x45), length 92
11:25:00.890782 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0x46), length 92
11:25:05.899056 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0x47), length 92
11:25:10.908124 IP 198.51.100.75 > 198.51.100.4: ESP(spi=0xc155682b,seq=0x48), length 92
Responder-Seite: Intern
Wir können also sicher sein, dass die verschlüsselten Pakete auch am Gateway der Filiale ankommen! Die letzte Etappe ist nun die interne Schnittstelle des Filial-Gateways. Hier schauen wir, ob das ICMP-Paket auch ins interne Netz Richtung Zielhost geschickt wird:
tcpdump -i A1 proto 1 -n
Ist auch auf dem Gateway der Filiale in Bezug auf Portfilter-Regeln alles korrekt konfiguriert, sollte sich folgende Ausgabe ergeben:
11:32:11.592831 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
11:32:16.733971 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
11:32:21.742500 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
11:32:26.753739 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
Daraus können wir eindeutig ersehen, dass der Zielhost zu mindestens online und physikalisch erreichbar ist. Warum können wir uns da so sicher sein? Das wird deutlich, wenn wir uns die Ausgabe anschauen, die wir erhalten, wenn wir anstatt des Protokolls ICMP einmal nach Paketen des Zielhosts suchen:
root@standort-4:~# tcpdump -i A1 host 10.4.0.10 -n
11:44:39.553889 ARP, Request who-has 10.4.0.10 tell 10.4.0.1, length 28
11:44:39.554212 ARP, Reply 10.4.0.10 is-at 08:00:27:e1:fd:ab, length 46
11:44:39.672145 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
11:44:44.682827 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
11:44:49.692773 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
11:44:49.699543 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
Wir sehen hier, dass vor unseren Pings vom Gateway ein ARP Request ins interne Netz gesendet wird, mit dem die MAC-Adresse des Zielhosts ermittelt werden soll. Darauf erfolgt eine Antwort des Zielhosts, in der er diese mitteilt. Erst dann können IP-Pakete an den Zielhost übermittelt werden. Die Ergebnisse von ARP Requests werden in der Neighbor table, auch ARP-Cache genannt, zwischengespeichert, so dass nicht für jedes IP-Paket ein neuer ARP Request durchgeführt werden muss. Diesen können wir uns mit folgendem Kommando anschauen:
ip n
Wir finden in der Ausgabe unter anderem einen Eintrag, der zu unserem Zielhost gehört:
10.4.0.10 dev A1 lladdr 08:00:27:e1:fd:ab REACHABLE
Das beweist eindeutig, dass der Zielhost online und physikalisch erreichbar ist. Wäre er das nicht, würde in der Neighbour table folgender Eintrag stehen:
10.4.0.10 dev A1 FAILED
Sofern das Gateway zu mindestens versucht, ein Paket an den Zielhost zuzustellen, liegt der Fehler nicht mehr innerhalb der Tunnel- oder Firewall-Konfiguration, sondern eindeutig am Zielhost. Entweder sehen wir keine IP-Pakete, aber einen Eintrag in die Neighbour table, der uns anzeigt, dass der Zielhost physikalisch nicht erreichbar ist. Oder wir sehen ein IP-Paket und können daraus schließen, dass der Zielhost zwar physikalisch erreichbar ist, aber auf die Verbindungsanfrage aus irgendwelchen Gründen nicht antwortet.
Mögliche Fehlerquellen auf dem Zielhost
Nachdem feststeht, dass der Fehler nur auf dem Zielhost liegen kann, müsste dieser auch dort gefunden werden. Wir können den Fehler aber auch bereits auf dem Gateway auf Responder-Seite weiter eingrenzen, wenn wir betrachten, ob und welche Pakete vom Zielhost zurückkommen:
tcpdump -i A1 host 10.4.0.10 -n
Sind nun ausschließlich die von der NextGen UTM ausgehenden Ping sichtbar, dann ist anzunehmen, dass der Zielhost aufgrund einer aktiven lokalen Firewall nicht antwortet:
11:32:11.592831 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
11:32:16.733971 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
11:32:21.742500 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
11:32:26.753739 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
Bei folgendem Fehlerbild kann von einer falsch gesetzten Subnetzmaske in der Netzwerkkonfiguration des Zielhosts ausgegangen werden:
11:32:11.592831 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
11:32:39.553889 ARP, Request who-has 10.0.0.10 tell 10.4.0.10, length 28
11:32:16.733971 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
11:32:39.553889 ARP, Request who-has 10.0.0.10 tell 10.4.0.10, length 28
11:32:21.742500 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
11:32:39.553889 ARP, Request who-has 10.0.0.10 tell 10.4.0.10, length 28
11:32:26.753739 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
11:32:39.553889 ARP, Request who-has 10.0.0.10 tell 10.4.0.10, length 28
Der Zielhost versucht, mit einer ARP-Anfrage die MAC-Adresse des Quellhosts zu ermitteln, als wäre dieser im gleichen Subnetz. Das weist eindeutig auf eine fehlerhafte Subnetzmaske hin. Selbst ein falsch gesetztes Default Gateway lässt sich so herausfinden:
11:32:11.592831 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 1, length 40
11:32:39.553889 ARP, Request who-has 10.4.0.254 tell 10.4.0.10, length 28
11:32:16.733971 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 2, length 40
11:32:39.553889 ARP, Request who-has 10.4.0.254 tell 10.4.0.10, length 28
11:32:21.742500 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 3, length 40
11:32:39.553889 ARP, Request who-has 10.4.0.254 tell 10.4.0.10, length 28
11:32:26.753739 IP 10.0.0.10 > 10.4.0.10: ICMP echo request, id 512, seq 4, length 40
11:32:39.553889 ARP, Request who-has 10.4.0.254 tell 10.4.0.10, length 28
Weitere Diagnosemöglichkeiten bei tcp-Verbindungen
Über die reine Erreichbarkeit eines Hosts hinaus lassen sich noch weitere Aspekte einer Verbindung untersuchen, wie zum Beispiel der korrekte Aufbau des TCP 3-Wege-Handshakes. Ist in der Antwort auf das initiale Paket (SYN-Flag) das RST-Flag gesetzt, dann wird der Zielhost zwar erreicht, der entsprechende Dienst ist aber nicht erreichbar:
root@standort-4:~# tcpdump -i A1 port 3389 -n
14:24:14.433460 IP 10.0.0.10.50795 > 10.4.0.10.3389: Flags [S], seq 315479174, win 64240, options [mss 1341,nop,wscale 8,nop,nop,sackOK], length 0
14:24:14.433725 IP 10.4.0.10.3389 > 10.0.0.10.50795: Flags [R.], seq 0, ack 315479175, win 0, length 0
Noch viel tiefergehende Analysen des Datenstroms können erfolgen, wenn dieser komplett mitgeschnitten und in einem Analysetool wie Wireshark untersucht wird:
root@standort-4:~# tcpdump -i A1 port 25 -w /tmp/dump.txt -s 0 -n tcpdump: listening on A1, link-type EN10MB (Ethernet), capture size 262144 bytes 12 packets captured 12 packets received by filter 0 packets dropped by kernel