< Firewall-Konzept > < zurück >
Ein grober Überblick über die Funktionsweise des Paketfilters
Den eigentlichen Artikel zum Thema Firewall-Konzept begleitend werfe ich hier einmal einen kurzen Blick auf die Basics des Paketfilters im Linux-Kernel. Ich halte diesen kurzen Abstecher ins technische für durchaus interessant, um schließlich darüber besser zu verstehen, was der Begriff „Firewall“ überhaupt bedeutet, und um dann zu erkennen, dass der Begriff „Paketfilter“ tatsächlich viel passender ist. „Firewall“ selber umfasst meiner Meinung nach nämlich nicht nur den Paketfilter im Kernel, sondern alles, das gesamte Konzept, angefangen mit den sachlich/organisatorisch/personellen Anweisungen und Regeln, dann dem zusätzlichen Hardware-Einsatz und erst ganz am Ende den tief im Betriebssystem des Linux-Kernels verankerten Paketfilter. Der Paketfilter ist also tatsächlich nur eine von mehreren Komponenten einer sicheren Firewall. Wie ich bereits zuvor schon festgestellt habe, wird die Firewall durch die Netfilter-Module direkt im Kernel ermöglicht. Die für diese Module notwendigen Informationen, was diese Firewall überhaupt tun soll, sind in speziellen Tabellen hinterlegt, die Tabellen enthalten Ketten, in denen wiederum die Regeln enthalten sind.
Tabellen = Tables
Ketten = Chains
Regeln = Rules
Der Linux-Kernel selber beinhaltet alle notwendigen Programmroutinen für die elementaren Netzwerk-Funktionen. Das heißt, der Kernel kümmert sich um die Verwaltung der Sockets, der Übertragungsprotokolle, den Netzwerkspeicher. Er implementiert das Handling der Hardware, wie z.B. für die Controller für eth0 und wlan0 über die passende Firmware oder Gerätetreiber. Und ganz am Ende enthält er natürlich auch über die Netfilter-Module die Routinen des Paketfilters. Ums kurz zu sagen, alle Datenpakete, die von irgendwo an der Netzwerk-Schnittstelle unseres PCs ankommen, und ebenso alle Datenpakete, die von irgendeinem Prozess unseres Rechners ausgehend an die Netzwerk- Schnittstelle gesendet werden, müssen ausnahmslos den Kernel und die Tabellen des Paketfilters passieren.
Die Rules einer Chain kann man sich bildhaft mit den Gliedern einer Kette vorstellen. Wenn für ein IP-Paket die passende Tabelle festgestellt wurde, wird das IP-Paket in den Chains auf Übereinstimmung der Match-Bedingungen geprüft. Die Prüfungen fangen am obersten Glied an, also mit der ersten Regel und werden solange von Glied zu Glied fortgesetzt, bis ein Regelergebnis ein "abschließendes" Urteil fällt. Das bedeutet, jedes Ketten-Glied (Regel) führt über vorgegebene Parameter eine Prüfung auf einen besonderen Zustand des zu untersuchenden IP-Paketes durch. Stimmt der mit den Parametern vorgegebene Zustand (Iptables matches) genau mit dem Zustand des IP-Paketes überein, so gilt das Ergebnis dieser Regel... was in meinen Beispielen zumeist ACCEPT bedeutet. In diesem Fall ist die weitere Verarbeitung der Chain nicht mehr notwendig, es ist entschieden, wie mit diesem IP-Paket zu verfahren ist, es wird mit ACCEPT angenommen und verarbeitet. Sofern allerdings keine einzige Regel passt und das IP-Paket alle Regeln passiert hat, entscheiden die Policies des Filters, wie ganz am Ende mit dem Paket zu verfahren ist. Da meine Regeln immer auf "ist das erlaubt?" prüfen, laufen alle Pakete, für die keine Regel gefunden wurde, automatisch in den Policy-DROP.
Die folgende einfache Grafik zeigt bezogen auf den Paketfilter die Tabelle Filter, die Chains Input, Output und Forward und grob skizziert die möglichen Laufwege eines Datenpaketes
|
An dieser Stelle möchte ich noch mal kurz darauf hinweisen, dass das jetzt hier kein Handbuch für die Anwendung des Netfilters wird. Ich befasse mich hier wirklich nur sehr oberflächlich mit einigen wenigen hier relevanten Grundlagen und kratze damit tatsächlich nur geringfügig an den sehr umfassenden Möglichkeiten, die das Packetfiltering bietet. Der Paketfilter bietet Möglichkeiten, die das, was ich für mich als notwendig und sinnvoll erachte, weit übersteigen. Also bitte daran denken, meine Ausführungen sind hier nicht vollständig und umfassen allenfalls einige wenige Aspekte…. ich möchte mich eigentlich weitestgehend zielgerichtet auf meine Anforderungen beschränken und belasse es bei einigen grundsätzlichen Erläuterungen zu den Basics des Paketfilters.
Wenn ein Datenpaket am Interface ankommt, wird zuerst im Filter pre-routing geprüft, ob dieser Host der Empfänger des Paketes ist, also irgendein lokaler Prozess. Wenn ja, wird das Paket über den Paket-Filter INPUT an den lokalen Prozess gesendet. Wenn dieser Host nicht der Empfänger ist, wird das Paket über den Filter FORWARD an den Filter post-routing und von dort schließlich an das Network-Interface weitergeleitet, von wo es dann auf die Reise durch das LAN/WAN geht. Soviel zu ankommenden Paketen, nun fehlt noch ein kurzer Blick auf den ausgehenden Paketverkehr. Wenn ein lokaler Prozess ein Datenpaket sendet, passiert das Paket (bevor es den Rechner über das Netzwerk-Interface) zuerst den Filter OUTPUT und dann den Filter post-routing.
Insgesamt haben wir es also hier mit 5 unterschiedlichen Filtern zu tun:
- pre-routing
- INPUT
- FORWARD
- OUTPUT
- post-routing
Für den Transport eines Datenpaketes durch diese Filter gelten einige wenige einfache Grundlagen:
1. | Die Filter INPUT, FORWARD, and OUTPUT sind exklusiv, ein Datenpaket kann immer nur in einem dieser 3 Filter behandelt werden | |
2. | Ist dieser Host das Ziel des Paketes, wird der Filter INPUT verwendet | |
3. | Ist dieser Host die Quelle eines Paketes (irgendeines Anwendungsprogramms), wird der Filter OUTPUT verwendet | |
4. | Ist dieser Host weder Ziel noch Quelle (von einem anderen Host und für einen anderen Host), wird der Filter FORWARD verwendet |
Was sind aber überhaupt diese 3 Filter INPUT, OUTPUT und FORWARD, was enthalten sie? Jeder Filter ist zunächst mal auch nur eine Tabelle, und jede dieser Tabellen enthält eine unbestimmte Anzahl von einzelnen Regeln, die wie bei einer Kette (CHAIN) von oben nach unten durchlaufen werden. Ein Datenpaket wird also solange in der entsprechenden CHAIN geprüft, bis eine der vorhandenen Regeln eine abschließende Entscheidung trifft. Eine solche Entscheidung kann lauten, das Paket anzunehmen (ACCEPT) oder alternativ dieses Paket abzulehnen (DROP). Wenn keine der Regeln eine Entscheidung treffen kann, weil keine der in den Regeln vorhandenen Matchbedingungen auf das Paket passt, so werden die Default-Einstellungen des Filters verwendet. Üblicherweise ist ACCEPT die Vorgabe-Entscheidung, damit überhaupt eine Netzwerkfunktion möglich ist, auch wenn gar keine Paketfilter-Regeln gesetzt sind.
Mit der nebenstehenden Grafik sollten die Zusammenhänge etwas deutlicher werden. Und dabei wird auch der Unterschied zwischen Filter und NAT ersichtlich, wobei die Tabelle „Filter“ eigentlich leicht zu verstehen ist. Komplizierter ist nur das ganze Thema NAT, wenn es um die beiden Chains pre-routing und post-routing geht. Dabei ist allerdings anzumerken, dass diese Chains meines Wissens nach ihren Schwerpunkt bei der Entwicklung eines Linux-Routers haben. Ich selber benötige die Chain post-routing nur rudimentär zur Unterstützung meiner OpenVPN-Verbindungen. Die primäre Aufgabe von PREROUTING ist die Durchführung von DNAT für ankommende Pakete, die Aufgabe von POSTROUTING ist die Durchführung von SNAT für ausgehende und forwarded Pakete. Hierbei geht es im wesentlichen um Network-Access-Translation, womit eine Veränderung des Datenpaketes gemeint ist, und zwar einmal für Destination = Zieladresse (DNAT), einmal für Source = Quelladresse (SNAT). Wenn ich mich beispielsweise von irgendwo auf der Welt via OpenVPN mit meinem Server zuhause verbinde, um vielleicht sicher |
über das Heimnetzwerk surfen zu können, so haben meine ankommenden Pakete aus dem VPN-Netz einen fremden und abweichenden IP-Range im Vergleich zu meinem Heimnetzwerk. Das bedeutet, das Heim-Netzwerk würde wohl ein solches aus dem VPN ankommendes Paket raus ins Internet routen, aber es käme niemals eine Anwort zum VPN-Client zurück. Die Ziel-Adresse des VPN-Netzes ist im Heimnetz unbekannt, das Paket würde einfach verworfen werden. Um dieses Problem zu lösen, führt der VPN-Server vor dem Senden des Pakets ins Internet ein SNAT durch und ersetzt damit die Source-IP-Adresse des VPN-Paketes durch seine eigene Host-Adresse. Und wenn aus dem Internet ein Anwort-Paket zurückkommt, wird deswegen natürlich auch wieder dieser Host gefunden, das Paket enthält ja die gültige LAN-Adresse dieses Hosts. Und nun wird dort via DNAT die IP-Adresse des Host‘s wieder getauscht auf die IP des VPN, damit das Antwortpaket auch den Weg zurück zum VPN-Client findet.
So, genug damit, das muss aber jetzt und hier als nicht ganz so wichtige Nebenbei-Erläuterung genügen, denn das sind für mich hier nur Randaspekte, die ich nur mal eben mit Blick auf den großen Zusammenhang anreissen wollte. Und ich glaube, zum Verstehen meines einfachen Paketfilters reicht das auch aus. Deutlich tiefer gehendes Informationsaterial ist auf den Web-Seiten des Netfilter-Projects zu finden. Wer also seine „Firewall“ umfassend tunen will, findet dort alle notwendigen Infos.
Der aktuelle Stand im Linux-Kernel ist, dass derzeit zwei Möglichkeiten zum Einstellen von Regeln bestehen. Zum einen die traditionellen iptables und zum zweiten die moderneren nftables. Man kann davon ausgehen, dass die nftables irgendwann die iptables ablösen werden. Noch ist es aber nicht so weit, noch funktioniert beides. Für mein erstes Paketfilter-Modell, und zwar das für unsere Reise-Laptops, werde ich hier beide Lösungen zeigen. Funktional ist beides identisch, die nftables sind meiner Meinung nach nur ein wenig intuitiver in der Handhabung. Es kann allerdings sein, dass die nftables derzeit noch nicht zum Default-Umfang der Linux-Installation gehören. In diesem Fall wäre es notwendig, das Paket zu installieren.
apt install nftables
Welche Lösung man letztlich aber wählt, entscheiden allerdings die eigenen Vorlieben.