orm@doc-tcpip.org

Erstellt: Mai 2001 - Letzte Modifikation: Mai 2001

[ Main | Local ]


Werkzeug zur Paketanalyse auf dem Netzwerk

Tcpdump, Iptrace, Snoop, Ethereal

Tracen von IP-Verbindungen: Wie vorgehen?

IP-Tracing auf der AIX-Plattform: iptrace

AIX IPTrace Beispiele

Tcpdump - kann alles

Tcpdump Beispiele

Ethereal - Komfortabel und leistungsstark

IP-Tracing auf der SUN-Plattform: snoop

Wie setze ich einen Trace auf?

Das wichtigste ist, das man eine tragfähige Annahme über den Fehler hat. Nur so ist ein sinnvoller Trace möglich. Dann sollte man sich genau überlegen, auf welchem Host man was tracen möchte. Es ist z.B. keine guten Idee, in einer Telnet Session zum remoten Host einen Trace zu starten, der dann ein FTP-Fehlerszenario zwischen diesen Maschinen mitschneiden soll. (Man hätte dann beide Verbindungen gemischt im Trace..). Generell ist es gut, wenn man den Verkehr auf dem Link reduzieren kann und wirklich nur solange laufen läßt, bis der Fehler reproduziert ist.
Ein weiteres Problem sind Netzwerkkomponenten. Ein Switch sorgt z.B. für virtuelle Verbindungen, es sehen also nicht alle Hosts alle Pakete. Der Switch kopiert nicht alle Frames auf alle Ports, und man sieht dann nur Broadcasts oder geflutete Paket. Bei vielen Switches kann man einen Port auf einen anderen spiegeln und so den Verkehr mitschneiden. Hier ist allerdings Vorsicht angebracht. Die Konfiguration derartiger Komponenten ist komplex und häufig sind die Administratoren überfordert.
In solchen Fällen kann es nötig werden, sich physikalisch an eine bestimmte Stelle zu setzen und auf möglichst primitive Komponenten zurückzugreifen (also z.B. zwischen Host und Switch einen billigen Hub einfügen und mit einem Laptop tracen).
Dann, was auch gerne Vergessen wird, sieht man bestimmte Pakete nur an bestimmten Orten - vermutet man Probleme mit ARP oder anderen Broadcast, so muß man auf dem lokalen Netz bzw. in der Broadcast-Domain tracen.
Es ist jedenfalls immer besser, vorher nachzudenken statt hinterher durch mehrer hundert MB Trace zu waten.

Iptrace - das AIX-Standardwerkzeug

Das iptrace-Kommando ist das Arbeitspferd unter AIX.
Die angebotenen Features reichen für die allermeisten Zwecke aus, auch wenn man sich manchmal gut überlegen muß, wie man es anstellt. Es gibt sehr wenig Filtermöglichkeiten. Die Handhabung ist einfach, man kann den Dienst über den SRC bequem starten und stoppen. Es wird immer ein binäres Trace-File erzeugt, was man später mit dem Kommando ipreport formatieren muß. Es ist keine Online-Ausgabe nach STDOUT möglich. Die von ipreport erzeugten Ausgaben sind übersichtlich und die meisten Services werden ordentlich aufgelöst (DNS, DHCP, RPC, NFS, Portmapper). Mein letzter Stand ist, daß das Tool noch kein IPv6 kann.
Um den iptrace zur Verfügung zu haben muß das Fileset bos.net.tcp.server installiert sein.

Wenn man IPtrace startet, so liest es die Kommandozeilen Argumente ein, öffnet das Tracefile, setzt Signal-Handler auf, lädt die netintf-Kernelextension , öffnet einen raw AF_INET Socket und setzt das IFF_DEBUG-Flag auf dem Interface. AF_INET liest alle Pakete von allen Interfaces.

Die vorhandenen Schalter:
-a Keine ARP Pakete mitschneiden.
Das ist quasi Standard, es sei denn, man hat ein ARP Problem. -b Schaltet die -d und -s Flags in bidirektionalen Mode um. Das bedeutet: Man läßt den IPtrace alle Paket zum Host xyz tracen. So wird man nur die gesendeten Pakete sehen - mit -b sieht man dann auch die Pakete der Gegenrichtung (ist also genau wie die Angabe von -d und -s zusammen).
-d Host Alle Pakete zu diesem Host. Name oder IP Adresse. Mit dem -b Flag in beide Richtungen, also zum und vom Host.
-e Schaltet den "promiscuous mode" ein - wenn der Adapter das unterstützt. Dann sieht man alle Pakete auf dem Netz.
-i Interface Es werden alle Pakete, die auf diesem Interface ankommen oder gesendet werden, mitgeschnitten (also en0, tr0 ...).
-P Protocol Es werden alle Pakete mitgeschnitten, die für dieses Protokoll bestimmt sind. Man kann den Namen angeben, oder die Nummer aus /etc/protocols (ip 0, icmp 1, igmp 2, tcp 6, udp 17).
-p Port Dasselbe für die Portnummer - wenn man Verkehr über einen Port sehen möchte. Dezimalzahl oder die Namen aus /etc/services.
-s Host Alle Pakete von diesem Host. Name oder IP Adresse.
Mit dem -b Flag in beide Richtungen, also zum und vom Host.
Das ipreport-Kommando nimmt ein Tracefile als input und schreibt den formatierten Trace in ASCII nach STDOUT. Am besten leitet man in ein File um.

Hier die Schalter:
-c : Pakete anzeigen
-C: Checksummen prüfen
-e: In EBCDIC statt in ASCII ausgeben
-j : zum Paket Nummer springen
*-n: Pakete durchnummerieren
*-N: keine Namensauflösung
-r: RPC Pakete ausgeben
*-s: vor jede Zeile das Protokoll schreiben
-S: ein Sniffer File einlesen
-v: verbose
-x: Pakete in Hex ausgeben
-X : nur Bytes ausgeben
-1: compatibility: für AIX3.1 Traces nötig
Neu in 4.3.3:
-T: ein Tcpdump File einlesen

Beispiele zur Nutzung

Es ist am einfachsten, den iptrace-Service über den startsrc/stopsrc Mechanismus einzusetzen. Das spart die Suche nach der PID etc.
Folgender Trace schneidet keine ARP-Pakete mit (Schalter -a) und zeichnet den Verkehr zwischen den Hosts Cristina und Nimmaster auf. Das File mit den binären Daten ist /tmp/telnet.bin. Die Anführungsstriche begrenzen den String, den das startsrc-Kommando an den iptrace Prozesse übergibt. Die beiden "-a" haben also volle Berechtigung: das erste gehört zum Startsrc und zeigt an, das noch ein String mit Argumenten folgt. Das zweite "-a" ist für den IPTrace und zeigt an, das keine ARP Pakete mitgeschnitten werden sollen.

startsrc -s iptrace -a "-a -s cristina -d nimmaster /tmp/telnet.bin"

Mit ipreport muß der Trace formatiert werden. In diesem Format werden alle Pakete mit einer Nummer versehen (-n), es werden die RPC-Calls entsprechend aufgelöst (-r) und vor jede Zeile kommt eine dem Protokoll entsprechende Marke (-s). Die Abkürzungen sind selbsterklärend (TOK, ETH, TCP, DNS ...). Was das Flag "v" macht, habe ich nie so richtig verstanden.
In diesem Fall nicht eingesetzt, aber sehr vernünftig, wenn man in einem anderem Netz formatiert, ist das "-N" Flag. Es wird dann die Namensauflösung unterdrückt, und alles geht deutlich schneller.
Die Ausgabe des ipreports wird durch einen "grep" gejagt, und am Ende sind nur Pakete zu sehen, die über das Interface tr0 gingen.

ipreport -rnsv /tmp/telnet.bin |grep -p "interface tr0" |more
Hier Beispiele für Traces auf Ports. Einmal NTP (Port 123) und DNS (Port 53). Das sind sehr nützliche Ansätze zum Debuggen in diesem Bereich.
startsrc -s iptrace -a "-a -p 123 /tmp/ntp.bin"
startsrc -s iptrace -a "-a -p 53 -b /tmp/dns.bin"
Die Analyse eines Traces gestaltet sich sehr einfach, wenn man mit dem "grep" aus den ganzen Informationen gezielt einzelne Zeilen ausschneidet und direkt nebeneinander sehen kann. Ein Beispiel wären die Zeitstempel oder die Sequenznummern.
Folgender Befehlt reduziert jedes Paket auf 4 Zeilen: Das Interface (damit auch den Zeitstempel), Quell- und Ziel-Adressen (MAC) sowie die Sequenznummern und die Flags.
egrep "interface | src | th_seq | flags"
Es ist auf diese Art sehr einfach, im Trace eindeutige Marker zu bestimmen und dann die entsprechende Information herauszuziehen.

Tcpdump - sehr Leistungsfähig, sehr verbreitet

Gibt es hier: www.tcpdump.org

Tcpdump ist sicher das verbreiteste Tool dieser Art. Es ist für alle Unix-Plattformen zu haben, und für eine ganze Reihe anderer auch. Die Syntax ist etwas unübersichtlich und von Implementation zu Implementation auch verschieden. Trotzdem besticht tcpdump durch die Mächtigkeit und Vielfalt der Filter, die man konstruieren kann. Bei schwierigen Problemen geht meist kein Weg an tcpdump vorbei - wobei ein Blick in die man-Pages unumgänglich ist.

Die Filterregeln werden aus "Qualifiern" und "Keywörtern" zusammengesetzt und beziehen sich immer auf die angebene ID, entweder Hostname oder IP-Adresse.
Folgende Typen von Qualifiern sind erlaubt:

  • type - Welches Device wird mit der ID oder Zahlangesprochen.
    host, net, port - Default ist host

    Beispiele: host dumpy, net 192.168.14, port 123
    Verbindet das Device (host, net) mit der ID oder einer Zahl (dumpy, 123).
  • dir - Die Richtung (Direction) des Datenflußes bezogen auf die ID.
    src, dst, src or dst, src and dst - Der Default ist src or dst
    (src und dst sind "Source" und "Destination", klar.).

    Beispiele: src dumpy, dst net 192.168.14, src or dst port 123
    Bezogen auf eine ID wird die Richtung festgelegt.
  • proto - Man kann damit ein oder mehrer Protokole gezielt filtern.
    ether, ip, arp, rarp, udp, tcp - Default sind alle Protokole, die dem gegeben Type entsprechen.

    Beispiele: ether src dumpy, arp net 192.168.140, tcp port 2049.
    Ohne den "proto"-Qualifier würden alle für das Device möglichen Protokole angenommen: src dumpy ==> ip oder arp (also beide werden mitgeschnitten); net 192.168.140 ==> ip, arp, rarp und bei port 2049 würde sowohl udp wie tcp mitgeschnitten.
  • Es gibt natürlich noch mehr, die hier nicht so einfach reinpassen:
    broadcast, multicast, less, greater
  • Mathematische Operatoren:
    < greater, > lesser, >=, <=, =, != sowie +, -, *, /, &, |
  • Und natürlich and, or, not
Jetzt kann man sehr leistungsfähige Filter bauen:
  • "dst host dumpy" oder "ip src host dumpy"
  • "dst net NET" oder "dst port PORT"
  • "ip proto PROTOCOL
  • "(dst|src) host dumpy" - Wenn dst oder src oder beide "dumpy" zeigen
  • "ip src host dumpy" - Alle IP-Pakete von Dumpy
  • "tcp src port 123" - Alle TCP Pakete von Port 123
  • "ip proto protocol" - Entweder man gibt die Protokol-Nummer an oder die Namen: icmp, igmp, udp, tcp.
    Das sind zugleich auch Keywords, also muß man in diesem Zusammenhang mit einem Backslash (in ksh ) escapen.
  • "ether proto protocol" - Protokoll-Nummer (IP ist 0x800) oder Name (ip, arp, rarp).
    Man muß auch hier escapen, da die Namen auch als Keyword belegt sind.

Einige Beispiele aus dem richtigen Leben:

tcpdump -i tr0 -I tcp src port 2049
Zeigt auf dem Bildschirm fortlaufend (-I) alle TCP-Pakete, die vom Port 2049 kommen.
tcpdump -ien2 -w/tmp/tcpdump.bin !arp
tcpdump -I host dumpy and not port ftp and not port ftp-data
tcpdump -I host dumpy and not port ftp or ftp-data
Zeigt alle Pakete von Dumpy, die nicht zu einer FTP Verbindung gehören.
tcpdump -i tr0 -I tcp[13]& 3 !=0
Zeigt alle TCP Pakete, die ein SYN oder ein FIN enthalten.
Die Zuordnung der Zahlenwerte zu den Flags findet sich in der Datei /usr/include/netinet/tcp.h. Man muß beachten, das in diesem Header-File Hex-Werte stehen...
tcpdump -i tr0 -I -v > /tmp/ein.file
Paketgröße - 20 Byte IP-Header - 20 Byte TCP-Header = MSS
Mit -v bekommt man die TTL und die IP-Header ID.

tcpdump -Ipnitr0 proto 89
tcpdump -Initr0 proto 89 ==> promicuos mode
Zum Tracen von OSPF Problemen (Protokoll 89)
tcpdump -itr0 -w/tmp/tcpdump ip broadcast
Mit -w wird der Trace in ein File geschrieben. Hier wird nach IP Broadcasts gesucht.
Zum Auslesen des Files kann folgendes Kommando dienen:
tcpdump -evxr /tmp/tcpdump |more
Dabei sind: -e: Link Level Header: MAC, proto, paketlänge
. -n: keine Namensauflösung
. -v: time to live, type of service
. -x: print packet in hex
. -r: lesen von file

Ethereal - grafische Oberfläche und sehr leistungsfähig

Gibt es hier: www.ethereal.net

Wem das alles zu kompliziert ist, der kann zu Ethereal greifen. Das ist ein sehr umfangreiches und gutes, grafisches Tool. Es liest eine ganze Reihe anderer Formate ein und gibt die Pakete klar gegliedert wieder. Man kann mit dem dem Tool auch Filter aufsetzen und Traces fahren. Besonders schön ist, das man immer ein Fenster mit dem Hex-Dump hat. Klickt man mit der Maus auf eine Stelle, meinetwegen ein Flag oder eine MAC-Adresse, so erscheint die entsprechende Stelle im Hex-Dump hervorgehoben. Zum Lernen und als Arbeitspferd ideal. Trotzdem sollte man sich mit den propietären Tools der einzelnen Plattformen und tcpdump gut vertraut machen - schließlich kann es ja mal passieren, das man Ethereal nicht zur Hand hat...
Zum Tool selbst ist nicht viel zu sagen, es ist leicht verständlich, obwohl man seine Zeit braucht, um alle Features einsetzen zu können.

Snoop - Tracen unter SUN Solaris

Mit snoop habe ich wenig Erfahrung. Mir scheint es ein tcpdump auf Solaris zu sein, mit einer weniger kryptischen Bedienung.
Das wenige, was ich gemacht habe:
snoop -d nei0 between elrapido elbueno
snoop -d nei0 arp
snoop -d nei0 -o /tmp/snarf.bin -c 10000
Zum auslesen dieses Files geht man so vor:
snoop -i /tmp/snarf.bin > /tmp/snarf.out


[ Main | Local ]

[ Allgemein | UNIX | AIX | TCP-IP | TCP | ROUTING | DNS | NTP | NFS | FreeBSD | Linux | RPi | SMTP | Tracing | GPS | LW ]

Copyright 2001-2021 by Orm Hager - Es gilt die GPL
Feedback bitte an: Orm Hager (orm@doc-tcpip.org )