Weiter Zurück [Inhalt] Online Suche im Handbuch LITTLE-IDIOT NETWORKING

12.9 Die Programmierung von ipchains.

Zuerst sollte man die Versionsnummer von ipchains in Erfahrung bringen:

$ ipchains --version
ipchains 1.3.8, 27-Oct-1998

ipchains ist hervorragend dokumentiert. Insbesondere die Manpages sind sehr ausführlich. (man ipchains) Wer mehr über das Administrationswerkzeug wissen möchte, der sollte sich auch über ipfw informieren man 4 ipfw), oder die Quellcodes im Kernel selber einmal durchschauen, was aber Kenntnisse in der Programmiersprache C erfordert. Die Datei ist: /usr/src/linux/net/ipv4/ip_fw.c

Insbesondere sei aber die Referenzkarte von Scott Pronson in dem Quellpaket empfohlen, die im Postscript Format vorliegen.

Mit ipchains kann man verschiedenste Dinge regeln. Zuerst einmal kann man die Regeln in drei verschiedenen chains managen: input, output und forward. Letztere kann man nicht löschen.

  1. Eine neue chain erzeugen (-N).
  2. Eine leere chain löschen (-X).
  3. Die Policy für eine eingebaute chain ändern (-P).
  4. Alle Regeln in einer chain listen (-L).
  5. Alle Regeln in einer chain löschen (-F).
  6. Alle Pakete und Paketzähler in der chain zurücksetzen (-Z).

Es gibt verschiedene Wege, eine Regel in einer chain zu verändern:

  1. Eine Regel an eine chain anfügen (append) (-A).
  2. Eine Regel in einer chain einfügen (insert) (-I).
  3. Eine Regel in einer chain ersetzen (replace) (-R).
  4. Eine Regel in einer chain löschen (delete) (-D).
  5. Die erste Regel, die zutrifft in einer chain löschen (-D).

Es gibt noch ein paar weitere Optionen für das Masquerading:

  1. Zeige die momentan maskierten Regeln an (-M -L).
  2. Setze Timouts auf maskierte Pakete (-M -S). (Hinweis: I can't set masquerading timeouts!).

Die eventuell wichtigste Funktion erlaubt die Überprüfung der Regeln, hierzu mehr später.

Aufsetzen einer Regel

Die am häufigsten verwendeten Befehle werden sicher das Anhängen und Löschen von Regeln sein. Die anderen Befehle, wie das Einfügen und Ersetzen von Regeln sind einfach nur Varianten.

Jede Regel definiert einen Satz von Bedingungen, die, wenn sie die Regel erfüllen, angeben, wie mit dem Paket weiter zu verfahren ist.

127.0.0.1 ist per Definition das loopback interface, welches von vielen UNIX Programmen immer dann benutzt wird, wenn kein Netzwerk- Interface zur Kommunikation von Programmen untereinander zur Verfügung steht. Die Programme binden sich normalerweise an alle Interfaces gleichzeitig. Der Befehl ping sendet ein Paket vom Typ ICMP Nummer 8 (echo request), worauf der Host mit einem ICMP Paket Typ 0 (echo reply) antwortet. Ein Beispiel:

# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# ipchains -A input -s 127.0.0.1 -p icmp -j DENY
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
# 

Man kann hier gut erkennen, daß das erste Ping ein einmaliges Paket versendet, und ein Echo erscheint. Nach Programmierung des Kernels erscheint kein Echo mehr.

Die Syntax des Befehls ist recht einfach: Füge an die input chain eine Regel an, die Pakete mit dem Protokolls ICMP von der Quelladresse 127.0.0.1 verwirft.

Die Regel kann auf zwei Weisen wieder gelöscht werden. Zuerst kann die Regel, die die erste und einzige in der chain ist, unter Angabe der Nummer gelöscht werden.

        # ipchains -D input 1
        #

Die zweite Variante ist ein Löschen der Regel dadurch, daß man die Syntax der Regel noch einmal wiederholt, nur diesmal aber nicht anfügt (-A) sondern löscht (-D):

        # ipchains -D input -s 127.0.0.1 -p icmp -j DENY
        #

Existieren mehrere gleichlautende Regeln in der chain, so wird nur die erste Regel gelöscht, als vorsicht mit dem mehrfachen Aufruf von Skripten.

Filter Spezifikationen

Es wurden bisher nur die Optionen -p und -s eingeführt. Um auch Dienste auf Port- Ebene filtern zu können, sind zusätzliche Angaben notwendig. Genau hierum dreht sich dieses längere Kompendium.

Filtern nach Quell - und Zieladresse

Die Quell (-s) und Ziel (-d) IP-Adressen können im Prinzip auf vier verschiedene Arten erfolgen. Einmal können die IP-Adressen direkt als Quadrupel von vier Zahlen zwischen 0 und 255 angegeben werden, wie 127.0.0.1, zum anderen kann der Name eingesetzt werden, wie z.B. localhost. oder www.intra.net.

Der dritte und vierte Weg sind die Angaben der Netzwerk-Gruppen. Hier können Adressen, wie 10.0.0.0/24 oder 192.168.0.0/8 gemacht werden. Die Angaben mit einem /24 /16 oder /8 bezeichnen die signifikanten Bits (von rechts aus gesehen). /24 bedeutet, daß die letzen 3 Zahlen variiert werden dürfen. also alle IP - Nummern von 10.0.0.1 bis 10.254.254.254 verwendet werden dürfen, was dann einem Class-C Netz entspricht. /16 bezeichnet ein CLASS-B Netzwerk, und /8 ein CLASS-C Netzwerk mit 254 freien IP - Nummern. Die Bezeichnung /0 steht für jede IP - Nummer.

        # ipchains -A input -s 0/0 -j DENY
        #
Alternativ kann dann auch die Angabe -s 0/0 entfallen.

Invertierung von Adressen

Vielen Flags, inklusive den Flags -s und -d kann ein "!" vorangestellt werden, welches ein logisches nicht bedeutet. Dementsprechend bezeichnet ein -s ! localhost, jedes Paket, welches nicht von dem localhost stammt.

Filterung von Ports

Ein Protokolle kann mit dem -p Flag angegeben werden. Das Protokoll kann entweder eine Zahl, oder eine Bezeichnung für ein Protokoll sein. Diese sind in der Datei /etc/services angegeben. Beispiele sind ICMP, IGMP, IPX, TCP, UDP.... Es wird intern nicht zwischen Groß- und Kleinschreibung unterschieden.

Der Protokollname kann ebenfalls invertiert werden. Bezeichnungen, wie -p ! TCP bezeichnen alle Protokolle, außer dem TCP Protokoll.

Filterung von Portbereichen

Für den Spezialfall, daß TCP oder UDP als Protokoll angegeben werden, kann ein weiteres Argument angegeben werden, nämlich ein Bereich von Ports. Siehe auch Fragmentierte IP-Pakete. Ein Bereich wird mit dem Zusatz 6000:6010 oder auch nur :1023 bezeichnet. Die Syntax lautet dann -p TCP -s 0.0.0.0/0 :1023 für ein Paket, welches als Quellport einen Port unterhalb von 1024 eingetragen hat.

Auch hier können die Portbereiche invertiert werden. Das Beispiel:

-p TCP -d 0.0.0.0/0 ! www

bezeichnet alle Ports, die nicht Port 80 entsprechen. Man sollte auch stets auf die Position des Ausrufezeichens achten. Die Bezeichnung

-p TCP -d ! 192.168.1.1 www

unterscheidet sich von

-p TCP -d 192.168.1.1 ! www

Das erste Beispiel bezeichnet ein Paket, welches an alle Hosts auf Port 80, außer dem bestimmten Host adressiert werden darf. Im zweiten Fall darf nur dieser Host adressiert werden, aber nicht auf Port 80.

Zum Schuß bleibt noch die Klärung folgender Bezeichnung:

-p TCP -d ! 192.168.1.1 ! www

Dieses bezeichnet ein Paket, welches an alle Hosts außer dem bestimmten Host adressiert werden darf, und dort auf alle Ports zugreifen darf, außer dem Port 80. Generell gilt, daß alle Angaben, die hintereinander erfolgen, ein logisches und implizieren.

Filterung von ICMP

ICMP besitzt zwar Optionen als Argument, diese bezeichnen aber keine Portnummern, sondern beziehen sich auf Codes. Eine Invertierung, wie bei obigen Protokollen, ist nicht erlaubt.

ICMP Codebezeichnungen sind recht lang, daher werden häufig nur die Kurzbezeichnungen angegeben.

Number  Name                     Funktion

0       echo-reply               ping
3       destination-unreachable  Router, Clients
5       redirect                 Router
8       echo-request             ping
11      time-exceeded            traceroute

Keinesfalls sollten alle ICMP Pakete in Firewalls gesperrt werden. Der Code Nummer 3, destination unreachable ist ein unentbehrliches Hilfsmittel für korrektes Routing. Es könnten so eventuell Leitungen überlastet werden, insbesondere ISDN.

Die Zuordnung der Netzwerkkarte

Die Option -i ordnet eine Regel eindeutig einem Interface zu.

Im Gegensatz zu dem alten Firewall-Kernel ist es hier erlaubt, bereits eine Regel für ein Interface zu definieren, bevor es überhaupt existiert. Diese Eigenschaft erlaubt es, Regeln für ISDN-Interfaces aufzusetzen, ohne deren IP - Nummer zu kennen. Das trifft insbesondere auf dial on demand ISDN-Leitungen zu, deren IP - Nummer erst nach der Einwahl vergeben wird.

Bei der Bezeichnung der Interfaces sind auch wildcards erlaubt, wie z.B. ippp+ oder ppp+ oder eth+.

Die Invertierung der Interface Bezeichnungen mit einem Ausrufezeichen ist erlaubt. Dies bedeutet insbesondere, daß mit ! eth+ alle Interfaces, außer den Netzwerkkarten gemeint sind. Die Regeln treffen dann beispielsweise auf alle ISDN-Interfaces zu.

Filterung von TCP Paketen

Manchmal ist es sinnvoll, Verbindungen nur in eine Richtung zuzulassen. So ist es die Regel, den Datenverkehr aus dem Intranet zu Servern im Internet zuzulassen, ohne daß jedoch ein Angreifer aus dem Intranet Zugriff auf den Host im Intranet hat.

Der naive User würde also alle TCP Pakete, die aus dem Internet an der Firewall ankommen, verwerfen. Unglücklicherweise sollten nach einem Verbindungsaufbau die Antwortpakete die Firewall passieren dürfen.

Die Lösung ist, nur Pakete zu sperren, die erforderlich sind, um eine Verbindung aufzubauen. Diese haben per Definition das SYN Flag gesetzt. Alle Antwortpakete haben das ACK Flag gesetzt. Die Firewall merkt sich also, ob eine Verbindung von innen in das Internet initiiert wurde, und ob Antwortpakete zurück erwartet werden.

Die Option -y ist genau für diesen Zweck bestimmt worden. Diese Option ist nur und ausschließlich bei TCP Protokollen möglich und sinnvoll:

-p TCP -s 192.168.1.1 -y

Hier werden alle TCP Pakete zugelassen, die von dem internen Host 192.168.1.1 ausgehen, und an beliebige Hosts im Internet adressiert sind. Für diesen Host werden dann Antwortpakete aus dem Internet zurück erwartet. Ein direkter Zugriff aus dem Internet auf den Host im Intranet ist nicht möglich.

Auch hier kann der Sinn der Option logisch invertiert werden. Ein vorangestelltes Ausrufezeichen, wie hier im Beispiel:

-p TCP -s 192.168.1.1 ! -y

besagt, daß alle Hosts aus dem Internet auf den Host im Intranet zugreifen dürfen, von diesem aber keine Verbindung zu einem Host in das Internet aufgebaut werden darf. Das macht immer dann einen Sinn, wenn z.B. ein Datenbankserver im Internet gesichert werden soll. Für den Fall, daß es einem Angreifer gelungen ist, mit einem buffer overflow an eine Rootshell unter UNIX zu gelangen. Will er nun mit einer FTP-Verbindung die Daten entführen, so wird dies von der Firewall unterbunden. Der Angreifer muß also noch erhebliche Mühen investieren. Die Firewall hätte den Entführungsversuch dann aber bereits registriert.

IP-Fragmente

In vielen Fällen ist ein Paket zu groß, um direkt von dem Interface aufgenommen werden zu können. Daher wird es in kleine Fragmente aufgeteilt und versendet. Am anderen Ende müssen diese Fragmente wieder zusammengesetzt, also reassembliert werden, wie es in Fachsprache heißt.

Es gibt eine Reihe von Angriffsvarianten, die auf verschachtelten, IP-Fragmenten mit verschiedenen Offsets beruhen. Um diese Angriffe zu verhindern, ist es unerläßlich, daß der der Kernel diese IP-Fragmente vor der Weiterleitung an die Filter vollständig reassembliert. Bei der Kompliation des Kernels ist also beim Aufbau einer Firewall strengstens darauf zu achten, daß die Option: IP: always defragment aktiviert wird. Beim Einsatz als Router oder Switch wird sich diese Option negativ auf die Performance aus.

Dieser Tatsache wird in den Filterregeln Rechnung getragen. Das erste Fragment trägt den Header mit allen Informationen über IP-Adresse, Ports, Flags, Protokoll.....Alle weiteren Pakete sind für die Firewall nicht zuzuordnen und werden daher generell abgelehnt. Falls es also Probleme mit der Übertragung von Paketen kommt, ist die fehlende Defragmentierung auf der IP-Ebene die Ursache.

Es ist aber möglich, mit Hilfe des -f flag Regeln für TCP Pakete ohne SYN-Flag das Passieren der Firewall zu erlauben. Dies kann insbesondere dann der Fall sein, wenn die Firewall als Router oder als Firewall-Switch eingesetzt wird.

Eine Invertierung mit dem Ausrufezeichen ist für die Option -f erlaubt.

Short Frames, oder auch malformed packets werden vom Kernel als Fragmente behandelt. Diese können auch bei defekten Netzwerkkarten auftreten. Hier werden Logeinträge vorgenommen, also Vorsicht bei der Interpretation dieser Einträge.

Folgendes Beispiel beschreibt eine Firewallregel, die alle Fragmente verwirft, die als Zieladresse die interne IP - Nummer 192.168.1.1 beinhalten.

 
ipchains -A output -f -D 192.168.1.1 -j DENY

Pakete, die über große Strecken aus dem Internet an z.B. die Firewall herangetragen werden, sind häufig fragmentiert. Pakete aus der unmittelbaren Nähe sind niemals fragmentiert. Ein Angreifer, der sein Glück mit verschachtelten Fragmenten versucht, wird aus Gründen des exakten Timings immer versuchen, diese von einem Host aus nächster Nähe zu generieren, z.B. direkt von dem Bastion host in der DMZ. Aufgrund der Zuordnung IP-Adresse zu fragmentierten Paketen läßt sich direkt ablesen, ob ein solcher Angriff stattfindet, oder ob es nur ein gewöhnliches Paket aus dem Internet ist. Zugegeben, die Erstellung der Regeln ist nicht gerade trivial, aber es ist unerläßlich, diese Angriffsmethoden zu kennen, wenn man es mit Profis zu tun bekommt.


Weiter Zurück [Inhalt] Online Suche im Handbuch LITTLE-IDIOT NETWORKING