IP-Tables Skripte fuer Single Host, SMB-Server und Router

Aus Linupedia.org
Wechseln zu: Navigation, Suche

Der Paketfilter iptables ist ein sehr komplexer Paketfilter der viele Möglichkeiten bietet. Ein Paketfilter wie iptables arbeitet grundsätzlich auf der 3. und 4. OSI-Schicht, die auch als Vermittlunsschicht (auch Netzwerkschicht, englisch network layer) und der Transportschicht (eng. transport layer) arbeitet.


Was kann man mit diesen Informationen anfangen? Nun zum einen muss man wissen, dass der gesamte Internetverkehr wie wir ihn kennen über Datenpakete organisiert wird. Ein solches Datenpaket ist einfach ein Folge von Bits die hintereinander gesendet werden und bevor die eigentlichen Daten folgen Steuerindormationen in einem Header besitzt. Auf Grund der Komplexität der im Internet eingestzten Technologien werden dabei diese Datenpakete ineinander geschachtelt wie die russischen Matruschkas, die ineinander verschachtelten Puppen. Das bedeutet einfach das in einem Datenpaket das man empfängt Datenpakete ineinander verschachtelt liegen, in einem typischen Fall sind das von außen nach innen Ethernet-Frame, IP-Datagramm, TCP-Segment, HTTP-Request. Der Paketfilter untersucht also ein IP-Datagramm (oder auch ein ICMP-Datagramm) und das dazugehörige UDP-Datagramme oder TCP-Segment in denen Informationen wie Ziel- und Quell IP-Adresse, die Portnummern und der Zustand einer TCP-Verbindung.

Die Portnummer sagen einem Rechner an welchen lauschenden Dienst er ein TCP-Segment schicken soll, so bedeutet beispielsweise der Port 80 dass eine Anfrage an einen Webserver gestellt wurde. Bevor wir uns aber genau anschauen wie IP-Tables arbeitet müssen wir uns noch den Drei-Wege Handshake betrachten. Dazu ist es unerläßlich sich den 3 Wegehandshake unter TCP zu betrachten:

Dreiwegehandshake1.jpg
Dreiwegehandshake2.jpg

Wir wollen dabei nicht zu sehr in die technischen Einzelheiten gehen, das kann man sich in entsprechenden Wikepediaartikeln selbst durchlesen, wichtig ist, das zunöchst eine Anfrage für einen Verbindungsaufbau erfolgt, das entsprechende Bit im TCP-Header ist das SYN Bit (steht für synchronize). Unter Synchronozise wird das Senden der Anfangsnummer des TCP-Segmentes verstanden, das aus Sicherheitsgründen nicht mit 1 beginnt, sondern mit einer zufällig ausgewählten laufenden Nummer. Wenn der anderer Rechner diesen Port freigeschaltet hat und ein Dienst an ihm horcht dann sendet dieser Rechner ein TCP-Segment mit einer Bestätigung zurück das sogenannte ACK-Bit (ACK=Acknowledgement=Bestätigung) und ebenfalls ein SYN BIT, für die andere Richtung werden also andere Nummern verianbart. Emfängt der erste Rechner diese Bestätigung sendet er zum Abschluß nur das ACK-Bit und beginnt mit der Übertragung. Das ganze kann noch etwas komplexer sein, aber für unsere Zwecke reichen diese Informationen, siehe Abbildung.

Wenn man iptables- Regeln formuliert, muss man sich über diesen 3-Wegehandshake immer im Klaren sein. Für eine Neu-Anfrage ist also das SYN-Bit ohne ACK-Bit gesetzt, dass kann ein Pakerfilter feststellen und so zwischen Paketen unterscheiden die eine Verbindung neu aufbauen, oder die zu einer bestehenden Verbindung gehören. Wichtig ist immer das man die Richtung und die Portnummern richtig intepretiert, dort werden die meisten Fehler begannen. Der Client also zum Beispiel ein Webbrowser trägt als Zielport in seine Pakete den Well-Known Port ein, in diesem Fall 80 für http, als Quellport wird ein beliebiger Portonkreten Dienst wie http, pop3 oder smtp anspricht. Die andere ist mit einem konkreten Prozeß auf dem Client verbunden, zum Beispiel einen Webbrowser.

Es gehören also 4 relevante Informationen zu einem Paket, die Rechner und Prozess adressieren, die Quell-IP, die Ziel-IP, die Quellportnummer und die Zielportnummer. Zusätzlich enthält der TCP-Header den Status der Verbindung, ist es eine Anfrage, eine Bestätigung oder ein normales Paket das zu einer aufgebauten Verbindung gehört.


Bevor wir nun in media res gehen (Für Nichtlateiner zum Pudels Kern vorstoßen) müssen wir uns die grundsätzlichen Verlauf der Pakete in iptables betrachten. In der Abbildung ist der Weg durch den Paketfilter im Linuxkernel vorgezeichnet, im linken Bild Pakete die ins LAN gelangen, entweder aus dem Außennetz (oft das Internet) oder von dem Firewallrechner selbst, im rechten Bild ist der Weg vom LAN ins Außennetz dargestellt

Iptables.jpg


Man erkennt dass der Paketfilter iptables in sogenannten Chains (Ketten) aufgeteilt ist, Diese Chains sind in der Abbildiung schraffiert. Zu den Chans gehören: PREROUTUNG, INPUT, OUTPUT, FORWARD und POSTROUTING. Diese Chains enthalten verschiedene Tables (Tabellen) die iptables ihren Namen geben. Nicht jede Kette enthält dabei alle Tabellen. Die Table Mangle ist dafür zuständig Pakete zu markieren, die Table Filter dient dazu Pakete zu filtern, dass bedeutet abzulehnen (deny) oder zu akzeptieren (accept). Die Table Nat schreibt die Ziel oder Quelladressen (und/oder Ports) um, ist also für das Network Adress Translation, das Masquerading (verallgemeinertes Source-NAT: überschrieben privater Pakete mit der zugwiesenen Adresse ders Providers), das Portforwarding (Portumleitung, z. B bei transparenten Proxies) und das Destination NAT (umschreiben der Pakete aus dem Internet, die an einen Server im Netz gedacht sind). Da NAT entweder vor oder nach den eigentlichen Filter einen Sinn ergibt ist auch nur eine NAT Tabl in den Chains PREROUTUNG und POSTROUTING sinnvoll. Die INPUT Chain ist für Pakete gedacht, die als Ziel lokale Prozessen auf dem Firewallrechner ansteuern, das können zum Beispiel Pakete sein, die zu ssh Verbindungen oder zu DNS-Anfragen gehören. OUTPUT ist die Chain für Pakte deren Uraprung lokale Prozesse des Firewallrechner sind. Die FORWARD Chain ist im Grunde die wichtigste Chain, denn sie ist für die Weiterleitung der Pakete aus dem lokalen Netz ins Internet bzw. umgekeht zuständig.

Durch Regeln (rules), die in ene Chain eingefügt, angehängt oder gelöscht werden, kann der Anwender definieren welche Pakete durchgelassen werden. Wie man diese Regeln erstellt, das schreibt iptables nicht vor. Der Filter Iptables ist also genaugenommen ein Werkzeug, mit dem sich ein Paketfilter einrichten lässt. Dabei gibt es ganz verschiedene Strategien.

Der Vorläufer von iptables, das ipchain untersuchte nur die IP-Adressen und Portnummern. Man musste also stets in beiden Richtungen sperren, um in inserem Beispiel zu bleiben, sowohl die Pakete vom Client zum Server als auch visa verce. Mit iptables lassen sich aber auch die Zustände von Verbindungen betrachten. Durch die gesetzten Bits kann man nämlich Neuanfragen von Paketen die zu bestehenden Verbindungen gehören unterscheiden. Diese Fähigkeit wird als stateful inspection (Betrachtung des Zustandes) bezeichnet. Dadurch ist es möglich alle rückwärtigen Pakete, die also zu bestehenden Verbindungen gehören zu erlauben und den Paketfilter so zu betreiben, indem man sich auf die Pakete konzentriert, die einen Verbindungsaufbau initieren. Dieser einfachen Strategie steht auch eine komplexere Strategie gegenüber die auch die zu einer bestehenden Verbindung gehörenden Pakete nicht generell sondern gezielt erlaubt. Diese etwas sichere aber aufwendige Strategie erwartet pro Dienst zwei Regelsätze, die einfache Strategie ein Regelsatz.

Bevor aber die unterschiedlichen Strategien an einem Beispiel gezeigt werden können, sollte der Umgang mit iptables betrachtet werden. Dazu formulieren wir ein einfaches Skript, das einen Paketfilter einrichtet, der alles verbietet, ganz nach dem Prinzip Verbiete zunächst alles und dann erlaube bestimmen Paketen den Verkehr:

#!/sbin/sh
################## Firewall die alles verbietet

# Programm
IPTABLES="/usr/sbin/iptables"

################## Alle Pakete der Grundeinstellung werden verworfen


$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP

################## Alle eventuell noch vorhandenen Regeln werden gelöscht

# Lösche alle Regeln aus der Filter Tabelle
$IPTABLES -F

# Lösche aller Regeln aus der NAT Tabelle
$IPTABLES -t nat -F

# Lösche alle selbstdefinierte Regeln
$IPTABLES -X


Ein solches Skript könnte man als Art ultimiativen Paketfilter betrachten, der alles dicht macht. Beim Testen sollte man sicher sein, dass man ein solches Skript nicht remote von einem anderen Rechner ausführt, denn dann sperrt man sich selber aus. Wie in solchen Bash-Skripten üblich, wird hier das Programm iptables nicht direkt aufgerufen, sondern es wird eine Variable gesetzt. Hier ein Code-Auschnitt aus dem Skript:

#Programm
IPTABLES="/usr/sbin/iptables"

Das ist sehr vernünftig, wenn man das Skript in Umgebungen einsetzen will, in denen das Programm iptables aus Sicherheitsgründen umbenannt oder in ein anderes Verzeichnis gesetzt worden ist. Dann muss nur diese eine Zeile angepasst werden. Außerdem erlaubt das auch Variablen auszulagern. Dazu aber später mehr.


Genaugenommen ist iptables also nur das Werkzeug mit der sich Paketfilter erstellen lassen. Was wie gefiltert wird, liegt daran, wie wir iptables konkret einsetzen. Nach den oben beschriebenen Skript wird zunächst alles verboten. Dann beginnt man einzelne Pakte zu erlauben. Dabei muss man berücksichtigen, dass auch auf dem Rechner selbst Programme ablaufen die über eine Netzwerkschnittstelle kommunizieren, selbst dann wenn der Rechner keinen Netzanschluß besitzt. Der Grund ist einfach, Programmentwickler müssen keine Fallunterschiede zwischen Programmteilen vornehmen, die auf entweder auf verteilten Rechnern oder alle auf den gleichen Rechner laufen. Läuft der Dienst auf dem gleichen Rechner so kann er über die lokale Schnittstelle mit der IP-Adresse 127.0.0.1 angesprochen werden. Um Prozesse, die auf dem lokalen Rechner laufen ungestört über diese lokale Schnittstelle kommunizieren zu lassen, können folgende einfache iptables Befehle verwendet werden, wobei wir der Vollständigkeithalber die Zuweisung der itables Programmdatei stehen lassen.

IPTABLES="/usr/sbin/iptables"

$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A INPUT  -i lo -j ACCEPT

Die Bedeutung der einzelnen Parameter:

-A bedeutet wir hängen einer Regel an eine existierende Chain (OUTPUT, INPUT, FORWARD etc.)
-o die Schnittstelle zu der das Paket gesendet wird
-i die Schnittstelle von der ein Paket empfangen wird
-j das Target (Ziel) was mit dem Paket geschehen soll, zum Beispiel ACCEPT (akzeptiere das Paket) oder DENY (Lehne es ab)

So betrachtet sagt die erste Regel: Hänge diese Regel an den Regelsatz ausgehende Pakete, die Regel lautet: Akzeptiere alle Pakete die über die lokale Schnittstelle gesendet werden

und die zweite Hänge diese Regel an den Regelsatz eingehende Pakete, die Regel lautet: Akzeptiere alle Pakete die über die lokale Schnittstelle empfangen werden

Mit anderen Worten sagen beide Regeln, erlauben allen lokalen Programmen die lokale Schnittstelle zu benutzen.




Quellen und weiterführende Links


zurück zum Netzwerk