Netfilter: Kernel-Komponenten
Das Netfilter-Framework besteht aus drei Komponenten: iptables, ebtables und arptables.
Iptables
Der Teil des Netfilter-Frameworks, der sich mit der Filterung und Manipulation von IPv4-Datagrammen befasst ist Iptables. Sein Pendant für IPv6 ist Ip6tables.
Iptables enthält mehrere unabhängige Tabellen mit Regelketten, in welchen die Paketfilter-Regeln gruppiert sind. Jede Tabelle enthält fest eingebaute Regelketten und kann zusätzlich benutzerdefinierte Regelketten aufnehmen.
Jede Regelkette ist eine Liste von Regeln, die jeweils für bestimmte Datagramme gelten und festlegen, was mit diesen Datagrammen passieren soll. Eingebaute Regelketten besitzen darüber hinaus eine Policy, die bestimmt, was mit einem Datagramm passieren soll, auf das keine Regel passt. Wenn keine Regel in einer benutzerdefinierten Kette passt, geht es mit der nächsten Regel derjenigen Kette weiter, aus der die benutzerdefinierte Kette angesprungen wurde.
Jede Regel besteht aus zwei Teilen: einer Beschreibung der Datagramme, für die diese Regel zuständig ist (Match) und einer Aktion, die auf diese Datagramme anzuwenden ist (Target).
Netfilter-Tabellen
Die Tabellen haben verschiedene Aufgaben.
- Die Tabelle filter ist zuständig für die Entscheidung, ob ein Datagramm weitergeleitet oder verworfen wird. Wenn ich keine Tabelle explizit angebe, arbeiten die Benutzerprogramme mit dieser. Hier gibt es die eingebauten Ketten INPUT, FORWARD und OUTPUT.
- Die Tabelle nat ist für die Adressumsetzung zuständig. Sie wird konsultiert, wenn ein Datagramm eine neue Verbindung aufbaut. Hier gibt es die eingebauten Ketten PREROUTING, OUTPUT und POSTROUTING.
- Die Tabelle mangle ist für spezielle Manipulationen der Datagramme zuständig. Hier gibt es die eingebauten Ketten PREROUTING, OUTPUT, INPUT, FORWARD und POSTROUTING.
- Mit der Tabelle raw kann ich Datagramme von der Verarbeitung durch die anderen Tabellen ausnehmen. Diese Tabelle wird vor ip_conntrack konsultiert. Hier gibt es die eingebauten Ketten PREROUTING und OUTPUT.
- Die Tabelle security ist für Mandatory Access Control (MAC) Netzwerk-Regeln zuständig. Hier gibt es die eingebauten Ketten INPUT, FORWARD und OUTPUT.
Welche der genannten Tabellen zur Verfügung stehen, hängt von den Optionen bei der Konfiguration des Kernels ab und welche Kernel-Module geladen sind.
Targets
Die Aktionen für Datagramme, auf die eine Paketfilter-Regel zutrifft,
werden Target genannt.
Beim Programm iptables werden sie mit der Option -j beziehungsweise
--jump angegeben.
Wenn eine Regel nicht auf ein Datagramm passt, wird die nächste Regel derselben Kette untersucht. Passt eine Regel auf ein Datagramm, bestimmt das Target, welche Regel als nächstes angewendet wird.
Target kann eines der folgenden sein:
- der Name einer benutzerdefinierten Regelkette: dann werden als nächstes die Regeln dieser Kette angewendet,
- ACCEPT: das Datagramm wird durchgelassen und keine weitere Regel mehr angewendet,
- DROP: das Datagramm wird verworfen und keine weitere Regel angewendet,
- QUEUE: das Datagramm wird an ein Programm im Userspace zur Begutachtung übergeben
- RETURN: in einer benutzerdefinierten Regelkette geht es zurück zur Kette, aus der diese angesprungen wurde, in einer eingebauten Kette wird die Policy auf das Datagramm angewendet.
Ist das Ende der eingebauten Regelkette erreicht und passte keine Regel mit endgültigem Target, wird die Policy der Kette auf das Datagramm angewendet. Die Policy darf kein Sprung zu einer anderen Regelkette und nicht RETURN sein.
Iptables-Extension-Module stellen weitere Targets sowie zusätzliche Match-Optionen für die Regeln bereit.
Einsprungspunkte für Paketfilterregeln
Die Kernel-Komponenten des Netfilter-Frameworks bestehen aus verschiedenen Einsprungspunkten im Kernel-Code zur Verarbeitung und Weiterleitung von Datagrammen, verschiedenen Regelketten nebst in ihnen enthaltenen Regeln sowie Kernel-Modulen mit dem Code für die Aktionen, die sich aus den Regeln ergeben.
Um die Einsprungspunkte zuordnen zu können, betrachte ich zunächst abstrakt den Weg, den ein Datagramm durch den Kernel zurücklegt. Dieses kann auf zwei Möglichkeiten in den Netzwerk-Code gelangen: über ein Netzwerkinterface (IN) oder wenn ein lokaler Prozess ein neues Datagramm erzeugt.
Bei einem Datagramm, das über einen Netzwerkadapter angekommen ist, wird eine Routing-Entscheidung getroffen und dann das Datagramm an einen lokalen Prozess ausgeliefert, oder über einen - meist anderen - Netzwerkadapter (OUT) versendet.
Ein lokal erzeugtes Datagramm wird nach der Routing-Entscheidung über den ermittelten Netzwerkadapter (OUT) versendet oder, falls es an einen anderen lokalen Prozess geht, an diesen ausgeliefert.
Es gibt fünf Einsprungspunkte für das Netfilter-Framework, deren Name im nachfolgenden Bild der entsprechenden Regelkette des Paketfilters entspricht.
Die erste Regelkette, die ein von außen kommendes Datagramm passiert ist PREROUTING. Diese Regelkette gibt es bei den Tabellen nat, mangle und raw.
Geht das Datagramm nach der Routing-Entscheidung an einen lokalen Prozess, passiert es als nächstes die Regelkette INPUT, die es bei den Tabellen filter, mangle und security gibt.
Geht das Datagramm stattdessen zu einer anderen Schnittstelle, um wieder versendet zu werden, passiert es als nächstes die Regelkette FORWARD, die es ebenfalls bei den Tabellen filter, mangle und security gibt.
Ein von einem lokalen Prozess erzeugtes Datagramm passiert als erstes die Regelkette OUTPUT, die es bei allen Tabellen gibt, und geht dann nach der Routing-Entscheidung zur sendenden Schnittstelle.
Unmittelbar vor dem Versenden passiert ein Datagramm die Regelkette POSTROUTING, die es bei den Tabellen nat und mangle gibt.
Bei der Behandlung eines Datagramms im Kernel konsultiert der Netfilter-Code an den verschiedenen Einsprungstellen die zugehörigen Regelketten und verfährt mit den Datagrammen entsprechend der darin enthaltenen Regeln.
Außer den vordefinierten Regelketten, deren Name den Einsprungspunkten entspricht, kann es benutzerdefinierte Regelketten geben, die über Sprunganweisungen in den Regeln erreicht werden. Diese Regelketten können beliebige Namen mit bis zu 31 Buchstaben haben. Es empfiehlt sich, hierfür Kleinbuchstaben zu verwenden, um die benutzerdefinierten Ketten von den vordefinierten leichter unterscheiden zu können.
Diese benutzerdefinierten Regelketten können die Regeln zusammenfassen und einfacher strukturieren, so dass die Firewall einfacher zu verstehen ist. Dazu muss man jedoch das Modell kennen, nach dem diese Regelketten verknüpft sind. Für OpenWrt beschreibe ich das Modell der Regelketten in einem der folgenden Kapitel.
Connection Tracking
Will ich meinen Paketfilter zustandsbezogen (stateful) betreiben, verwende ich die conntrack Module.
Diese haben den Vorteil, dass ich meine Regeln genauer bestimmen und trotzdem einfacher halten kann. Bestimmte Anwendungen, wie das automatische Freischalten von FTP-Datenverbindungen, gehen nicht ohne diese Module.
Ein Nachteil von zustandsbezogenen Paketfilter ist, dass sie für die zusätzlichen Informationen mehr Speicherplatz benötigen. Deshalb muss ich mir gegebenenfalls Gedanken machen, wie ich die Zustandstabellen vor Überlauf schützen kann.
Beim zustandsbezogenen Filtern kann ich die Datenpakete neben den anderen Kriterien noch nach dem Zustand der zugehörigen Verbindung diskriminieren. Diese Zustände sind:
- NEW
- für ein Paket, das eine neue Verbindung aufbaut.
- ESTABLISHED
- für Pakete, die zu einer bereits existierenden Verbindung gehören.
- RELATED
- für Datagramme, die zu einer bestehenden Verbindung gehören, aber nicht Teil dieser sind. Das kann ein Paket sein, das eine Datenverbindung zu einer bestehenden FTP-Verbindung aufbaut oder eine ICMP-Fehlermeldung.
- INVALID
- für ein Paket, das nicht identifiziert oder zugeordnet werden kann. Zum Beispiel ICMP-Fehlermeldungen oder TCP-Pakete, die zu keiner bekannten Verbindung passen.
Dabei muss ich beachten, dass der Status einer Verbindung bei Iptables nicht äquivalent zum Status einer TCP-Verbindung sein muss. So hat das SYN-ACK-Paket beim Aufbau einer TCP-Verbindung bei Iptables den Status ESTABLISHED, während die TCP-Verbindung erst mit dem dritten Datagramm als established angesehen wird.
Bei ICMP können nur vier Typen den Status NEW oder ESTABLISHED haben:
- Echo (0,8)
- Timestamp (13,14)
- Information (15,16)
- Adressmask (17,18)
Alle anderen ICMP-Nachrichten können maximal den Status RELATED haben.
Iptables-Extensions
Für einige Protokolle und andere nützliche Sachen gibt es sogenannte Match-Erweiterungen, für die zum Teil zusätzliche Kernel-Module geladen werden müssen.
Das sind beispielsweise Erweiterungen für die Protokolle ICMP, TCP und UDP,
mit denen ich die Regeln genauer an die Erfordernisse dieser Protokolle
anpassen kann.
Diese aktiviere ich mit der Option -p beim Aufruf von iptables.
Andere Erweiterungen beziehen sich auf die MAC-Adresse, die Limitierung von Datagrammen oder den Benutzer oder Prozess, der ein lokal erzeugtes Datagramm verursacht hat.
Weitere Erweiterungen, erlauben mir zusätzliche Targets, das heißt Aktionen, in den Regeln, wie zum Beispiel:
- LOG für das Protokollieren von Datagrammen
- REJECT um Fehlermeldungen für Datagramme zu generieren
- SNAT, DNAT, MASQUERADE um die Adressen zu manipulieren
- REDIRECT um eine Verbindung umzuleiten
- TOS und MARK um QoS zu unterstützen
Ebtables
Dieser Teil der Netfilter-Frameworks behandelt die Administration der Ethernet-Bridges.
Hier gibt es drei Tabellen mit vordefinierten Regelketten:
- Die Tabelle filter entscheidet über die Weiterleitung von Ethernet-Frames.
- Die Tabelle nat dient der Manipulation von Ethernet-Frames.
- In der Tabelle broute wird entschieden, ob ein Ethernet-Frame anhand der Layer-2-Informationen weiter geleitet werden soll (Bridge) oder anhand der Layer-3-Informationen geroutet werden soll. Das ist bei einem reinen IP-Betrieb kaum mehr notwendig. Falls im Netz jedoch anderer Traffic (zum Beispiel NetBEUI oder IPX) vorkommt, kann man damit einen sogenannten Brouter realisieren.
Arptables
Das Programm arptables wird verwendet, um die ARP-Regeln im Linux-Kernel zu
verwalten.
Diese Regeln inspizieren die ARP-Datagramme.
Es gibt nur eine Regeltabelle: filter. Diese enthält drei Regelketten:
- INPUT für Datagramme, die an diesen Rechner gehen,
- OUTPUT für Datagramme, die von diesem Rechner erzeugt wurden und
- FORWARD für Datagramme, die vom Bridge-Code weitergeleitet werden. Diese Kette gibt es beim Kernel 2.4 nicht.
Wenn eine Regel zutrifft, gibt es die folgenden Targets (Aktionen):
- ACCEPT, um das Datagramm durchzulassen.
- DROP, um das Datagramm zu verwerfen.
- CONTINUE, um die nächste Regel zu prüfen.
- RETURN um aus der aktuellen benutzerdefinierten Kette zurückzuspringen.
Daneben gibt es Target-Erweiterungen, die es erlauben, ARP-Datagramme zu manipulieren, indem die MAC- oder IP-Adressen geändert werden.