<alex@ynfonatic.de>Jaja, so geht's. Da gibt es einen neuen Kernel, und man muss schon
wieder ein neues Managementtool zur Linuxfirewall lernen. Am Anfang war
ipfwadm, und dannach kam ipchains. Kaum hatte man sich an
ipchains gewöhnt, kam iptables.
Nun, dieses Dokument ist eigentlich aus der Not entstanden. Ich habe mich schon sehr früh mit Netfilter beschäftigen müssen, da ich einem Projekt bei meinem Arbeitgeber eine Firewall auf Linuxbasis ausetzten sollte.
Es wurde sher früh klar, das ipchains "tot" ist und das es wenig Sinn macht, weiterhin darauf zu setzen. Also wurden eifrig die neusten Entwicklerkernel heruntergeladen, netfilter von Hand eingeklebt, kompiliert und getestet. Mitunter mit erbüchternden Folgen.
Nun ist der neue Linuxkernel in der Version 2.4.1 verfügbar, und Netfilter hat meiner Meinung nach (schon lange) einen Stand erreicht, der den Gebrauch im Produktionsbetrieb zulässt. Es gab nicht sehr viele Dokumente, die mir und meinen Kollegen beim Aufsetzen der ersten Netfilterfirewall geholfen haben, trotzdem gibt es vier wertvolle Quellen, die am Schluss erwähnt werden.
Ich will mit diesem Kochbuch das praktisch anwenden, was in den gegenwärtzigen HOWTO's noch unzureichend dokumentiert ist: Mit welcher Variante man welches Ergebniss erreichen kann. Das Dokument setzt Basiswissen im Bereich IP-Netze und Routing vorraus, Wissen über die alte Linuxfirewall und ipchains ist nützlich, aber nicht notwendig.
Dieses Dokument ist noch in einem sehr frühen Stadium, also bin ich über Hilfe, Anregungen, Anmerkungen und natütlich Berichtigungen jederzeit dankbar. Dieses Kochbuch hat eine Menge Kapitel, und mindestens genau so viele sind zur Zeit noch leer. Wenn Du, werter Leser, dich geneigt fühlst, ein leeres Kapitel zu vervollständigen und dich auch noch ein wenig mit dem Linuxdoc SGML System auskennst, dann schreibe mir einfach eine Email und teile mir mit, was du tun möchtest. Auch wäre ich daran interessiert, wenn sich Freiwillge zwecks Übersetzung in andere Sprachen bei mir melden würden.
Ich möchte noch von virneherein erwähnen, dass ich weder ein Kernelhacker noch ein Netfilterentwickler bin. Ich habe mir nur in viel mühseliger Kleinarbeit die Informationen zusammengesucht, die ich für das Firewallsetup an verschiedenen Standorten brauchte. Ich dachte mir, dass es nützlich wäre, dieses Wissen mit Euch zu teilen. Wie für alle Dokumente gilt hier auch: Benutzung auf eigene Gefahr ! Ich kann nicht garantieren, dass alles, was hier beschrieben ist, funktioniert, geschweige denn richtig ist. Für weitere Infos schaut in den Disclaimer und ins Copyright. Ausserdem habe ich sehr viele Informationen schamlos geklaut, teils aus "Rusty's unreliable Guides", aus der "Advanced Routing Howto", der "Linux packetfilter HOWTO" und der "Netfilter hacking HOWTO". Näheres gibts bei den Quellen.
Genug der Worte, los gehts ! Viel Spass beim Lesen,
Alexander "Yalla" Janßen < alex@ynfonatic.de>
Netfilter ist der neue Linux Firewall Mechanismus. Er ist integraler
Bestandteil des Netzwerkteils von Linux. Netfilter hängt sich,
salopp gesagt, in die Sende- und Empfangsleitungen von Linux ein. Wann
immer Daten in die Firewall fliessen oder verlassen, ist Netfilter am
Ball und trifft anhand von Regeln, die der Benutzer mit dem Tool
iptables erstellt, Entscheidungen, was mit diesen Daten passieren
soll.
Netfilter könnte sich entscheiden, die Daten passieren zu lassen, sie mitzuloggen, sie zu verwerfen, zurückzuweisen oder gar woanders hin umzuleiten. Netfilter könnte auch über den NAT-Mechanismus die Absender- oder Empfängeradresse oder Port austauschen, oder auch die Pakete markieren, damit sie der Routingmechanismus anders behandelt.
Kurzum: Netfilter ist in der Lage, Daten, die durch die Firewall fliessen, zu beeinflussen. Traditionell leiten Router ihre Pakete und deren Inhalt unbeinflusst weiter - eine Firewall kann jedoch vor oder nach dem Routing Entscheidungen treffen, das Paket nach Regeln zu behandeln.
iptables ist das Programm, mit der Linux 2.4 Firewall administriert
wird. Es fasst alle Funktionen wie NAT, mangeling und den Paketfilter unter
einer einheitlichen Syntax zusammen.
Die simpelste Firewall, die es wohl gibt, ist die, die den lokalen Rechner vor dem bösen Internet beschützt. Idealerweise ist eine Firewall so aufgebaut, dass man nur loakl abgehende Verbindungen aufbauen kann. Eingehende Verbindungen sollen so weit es geht und erwünscht ist, verboten werden.
"Warum", fragt sich nun der aufmerksame Leser, "brauche ich eine loakle Firewall ? Ich habe doch kein Netzwerk !". Nun, diese Frage ist nicht unberechtigt. In Zeiten, wo eine Flatrate mittlerweile in Deutschland erschwinglich ist, ist man gut und gerne 24 Stunden "online", bevor sich die IP durch einen zwanghaften Abbruch ändert. Eine IP, die sich für längere Zeit als ein und dasselbe Host zeigt, ist ein potielles Ziel für die selbsternannten "Hacker", den Script Kiddies. Ihnen wird es einen Heidenspass machen, dich zu attackieren, sobald sie wissen, dass es dich gibt !
Dies ist keine ungesunde Paranoia - man muss sich halt nur vor Augen halten, dass die Zeiten von "winnuke" vorbei sind. Ein gewöhnlicher User ist meistens nicht so auf dem Laufenden und sieht es auch gar nciht ein, seinen loaklem FTP-Server zu patchen, "nur" weil "wieder einmal" ein Fehler im wu-ftpd bekannt wurde. Aber Script Kiddies oder andere destruktive Naturen haben schneller einen Exploit zur Hand, ehe man bemerkt, dass man eigentlich angegriffen wird. Und eine Sicherheitslücke, die dem Angreifer eine Rootshell öffnet, hat eine ganz andere Qualität als ein abgestürzter Rechner. (FIXME: Besseres Beispiel einfügen, das mit ftp hinkt, da man eh verloren ist, wenn der Exploit angwandt wird)
Hier ein Beispiel, dass diesen Forderungen gerecht wird. Es sind, soweit an dieser Stelle zu erlätern, Kommentare angefügt.
# Lösche zuerst alle Regeln in allen Tabellen
ipatbles -t filter -F
iptables -t nat -F
ipatbles -t mangle -F
# Nun setzte alle Ketten defaultmässig auf "alles wegwerfen"
iptables -P INPUT DROP
iptables -P FORWARD DROP
# Nur die OUPUT-Kette, das sind die Daten, die die Firewall selber
# rausschickt, wird freigeschaltet
iptables -P OUTPUT ACCEPT
# Nun erlaube Daten, die von der Firewall selber kommen, auch die Firewall
# zu betreten (lo = Loopbackdevice aka 127.0.0.1)
iptables -A INPUT -i lo -j ACCEPT
# Erlaube Daten, die aus einer Verbindung stammen, die wir selber
# erzeugt haben, die Firewall zu betreten
ipatbles -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Diese minimale Firewall bietet also nun folgende Features:
Diese Firewall erlaubt wohlgemerkt sonst gar nicht. Möchte man aber z.B. einen FTP-Server öffnen, kann man das mit folgenden Befehl tun:
# FTP für den Zugriff von aussen freischalten
iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT
Analog dazu kann man auch seinen lokalen Webserver erlauben:
# Webzugriff freischalten
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Das ist meistens die brennenste Frage, die zuallererst geschrien wird: "Ich will doch nur Masquerading !" Ok, hier sollt ihr es haben. Ich habe das gesamte Setup schamlos aus Rusty's Netfilter Guide geklaut. (HIER EINFÜGEN)
Portforwarding ist, wenn eine Maschine einen Port bereitstellt, die Daten annimmt, die Verarbeitung aber letztendlich einer anderen Maschine überlässt. Am besten erlätert man dies an einem Beispiel:
Meine Firewall bietet keine FTP-Dienst an, soll sie auch gar nicht. Hinter meiner Firewall habe ich nun einen Rechner, der diese Aufgabe übernehmen soll. Die Firewall macht jedoch die Ports 21 und 20 auf und leitet alle Anfragen an den FTP-Host weiter. Der Benutzer denkt jedoch, dass er mit meiner Firewall spricht.
Der ganze Mechanismus wird durch NAT und Connectiontracking realisiert. Was passiert hier also im Detail ?
Die Firewall nimmt die Daten vom Client entgegen, vertauscht die Absenderadresse des Clients mit seiner eigenen, internen Adresse (unter der sie für den eigentlichen FTP-Server bekannt ist), öffnet einen neuen Port von dem sie aus quasi als Vermittler dem FTP-Server die Anfrage stellt.
Der FTP-Server redet also nun mit der Firewall. Die Firewall weiss nun über ihren Port, mit dem sie mit dem FTP-Server verbunden ist, zu welchem Client im Internet die Verbindung gehört.
Als Beispiel, wie sich ein Portforwarding in Verbindung mit NAT realisieren lässt, zeige ich, wie man das Spiel "Delta Force" aus einem Windowsrechner hinter der Firewall mit einer privaten IP hosten kann: (HIER EINFÜGEN)
iptables ist ein Tool, um Regeln in in die Firewall einzupflegen. Um
die Architektur im Detail zu verstehen, müssen ein paar Begriffe
eingeführt und erläutert werden.
Das Netfilter-Framework kennt insgesamt drei Standarttabellen. Die wohl
wichtigste Tabelle, die filter-Tabelle, nimmt Regeln für den
Paketfilter auf. Eine andere wichtige Tabelle, die nat-Tabelle; sie nimmt
Regeln zur Manipulation des Paketheaders auf. Dort findet z.B. Source-NAT,
Destination-NAT oder das bekannte IP Masquerading statt. Dazu mehr im Punkt
NAT. Die dritte, "grosse" Tabelle ist die mangle-Tabelle. In dieser
Tabelle lassen sich z.B. die TOS-Bits setzen oder die Pakete intern markieren
um im Routing-Code auf andere Wege zu schicken.
In jeder Tabelle befinden sich mindestens eine Chain. Die Chains nehmen die verschiedenen Regeln auf, die sich wiederum aus einem Match und einem Target zusammensetzen.
Eine Chain ist eine Abfolge von Firewallregeln. Die Regeln in einer Chain werden immer von oben nach unten abgearbeitet. Ein Paket wandert also in eine Chain hinein und der Match der ersten Regeln wird gegen das Paket geprüft. Trifft der Match zu, wird das Paket auf das Target angewandt. Das Target wiederum kann ein "finales" oder ein "nichtfinales" Target sein. Wird ein Paket auf ein finales Target angewandt, ist die Reise für dieses Paket in dieser Chain vorbei und das naechste Paket betritt die Chain. Ist es jedoch auf ein nichtfinales Target angewandt worden, wandert das Paket weiter durch die Chain.
Jede Chain zählt zusätzlich noch die Anzahl der Pakete mit, die in diese Chain gelangt sind. Auch zählt sie die Anzahl der effektiven Bytes mit.
Als Zusatzinformation bleibt noch zu sagen, dass man eigene Chains mit eigenen Regeln erstellen kann und beinahe beliebig zwischen den Chains hin- und herspringen kann (was effektiv heisst, dass man ein Paket von einer Stelle der Firewall zu anderen schickt).
Ein Match ist der Teil einer Regel, der bestimmt, welches Paket auf das Target angewandt wird. Hier mal ein Beispiel in Prosa und dannach in Code:
"Alle Pakete, die von 192.168.0.1 nach 192.168.1.6 gehen und zum Port 22/tcp
gehen"
-s 192.168.0.1 -d 192.168.1.6 -p tcp --dport 22
"Alle Pakete, die vom externen Interface kommen und keine ICMP-echo-requests
sind" (eth2 ist dabei das externe Interface)
-i eth2 -p ! icmp --icmp-type ! icmp-echo-request
Targets bestimmten letztendlich, was mit dem gematchten Paket gemacht werden soll. Hier mal eine Liste typischer Targets:
ACCEPT - Akzeptiere (erlaube) das Paket. Finales Target.DROP - Werfe das Paket wegREJECT - Weise das Paket mit einem Fehler zurüchkSNAT - Ersetze die Source IP-Adresse des Paketes durch eine andere
NAT ist die Abkürzung für "Network Address Translation". Mit dieser Funktion kann man die Absender- und Empfängeradresse eines Datenpaketes auf der Firewall so verändern, dass das Paket entweder woander hingeschickt wird (wenn DNAT - Destination NAT, also die destination IP verändert wurde) oder dass es so aussieht, als ob jemand anderes das Paket losgeschickt hat (SNAT - source NAT oder MASQUERADE).
Dieses sehr populälre NAT wird sehr häfig eingesetzt. Seine beiden Haupteinsatzgebiete sind einmal kleine, private Netzwerke, die nur eine einzige offizielle IP-Adresse besitzten aber trotzdem durch einen Router Zugriff auf's Internet von allen internen PC's mit privaten IP-Adressen haben wollen - im anderen Fall möchte man durch SNAT einfach verschleiern, das hinter der Firewall noch eine ganze Menge anderer Rechner stehen (daher auch der Name "Masquerading").
Das Mitloggen von Verbindungen ist ein wesentliches Feature, was man von jeder Firewall erwarten kann. Das Netfilter bietet gleich zwei verschiedene Logmechanismen, unter denen man auswählen kann.
Das LOG-Target ist ein Target, dass jedes Paket, das es empfaengt, zum syslogd schickt. Im System-Logfile finden sich dann die mitgeloggten Pakete.
Beispiel:
# Ein paar Variablen setzen, damit das Beispiel deutlich wird
EXTIF=ippp0
INTERNALIF=eth0
# Alle ftp-Zugriffe ins private Netz verbieten und mitloggen
iptables -t filter -A FORWARD -i $EXTIF -o $INTERNALIF -p tcp --dport 20:21 -j LOG
Falls nun vom Interface ippp0 ein Zugriff auf einen Rechner
erfolgt, der hinter dem Interface eth0 steht, der dem Protkoll TCP
und den Zielports 20 oder 21 (den FTP-Ports) erfolgt, wird dieses Paket
geloggt. Man muss sich aber merken, dass es nicht weggeworfen wird !
Dies muesste man im Anschluss noch tun.
Der dazugehörige Eintrag in /var/log/messeages wird dann in etwa so aussehen:
--- hier einfuegen ---
Das ULOG-Target ist wesentlich flexibler als das LOG-Target. Es tut im wesentlichen genau dass, was das LOG-Target auch tut, nur kann man sich aussuchen, was mit diesem Paket gemacht werden soll und welches Programm das Paket letztendlich bearbeitet. Es ist also nicht, wie LOG, auf den syslogd beschränkt.
Technisch gesehen schickt das ULOG-Target das Paket an eine lokale NETLINK-Multicast Gruppe. Ein beliebiges Programm, dass auf diese Gruppe hoert, kann dann das Paket entgegennehmen und etwas tun.
Das bekannteste Programm, was mit dem ULOG-Target zusammenarbeitet,
ist sicherlich der ulogd, der "Userspace Logging Daemon".
Ulogd arbeitet mit sogenannten Plugins, an die es die Daten
weiterreicht.
Das MySQL-Plugin fuer den ulogd ist wohl das momentan beste
Plugin, dass es gibt. Es schickt die Paketheader nicht in eine Datei,
sondern direkt ueber IP an einen beliebigen MySQL Datenbankserver. In
diesem DB-Server gibt es dann eine Datenbank, in der die Tabelle ist, wo
die Daten hineingeloggt werden.
Genau diesen Fall habe ich schon einmal gehabt, mich auf die Hinterbeine
gesetzt und doch noch gelöst bekommen. Ich werde das Script ohne viele
Kommentare hier einfügen - wenn dies jemand braucht, wird er dieses
Script schon verstehen. Aber grundsätzlich braucht man dafür das
Tool iproute2 und man muss Paketmangeling und fwmark-routing im Kernel
aktiviert haben. Was noch wichtig ist: Beide Netze sind 192.168.0.0/24, und
sie verwenden das 192.168.10.0/24'er Netz als Dummy-Netz. Wenn also der
Rechner 192.168.0.5 den Rechner 192.168.0.10 im anderen Netz bekommen will,
spricht er zu 192.168.10.5 - dies lässt sich mit einem gut aufgesetzen
DNS bewältigen, so dass der User nicht nachdenken muss.
#!/bin/bash
case "$1" in
start)
# Zähler für Klasse C Subnetz auf null setzen
i=0
# fwmark Classmark setzen
iptables -t mangle -A PREROUTING -i eth1 -s 192.168.0.2 \
-d 192.168.10.0/24 -j MARK --set-mark 0x1
iptables -t mangle -A PREROUTING -i eth2 -s 192.168.0.0/24 \
-d 192.168.10.0/24 -j MARK --set-mark 0x2
# Für das gesamte Subnetz die D-/ und SNAT Regeln in beide Richtungen
# aufsetzen
while [ "$i" != 256 ]
do
iptables -t nat -A PREROUTING -i eth1 -d 192.168.10.$i -j DNAT \
--to-destination 192.168.0.$i
iptables -t nat -A PREROUTING -i eth2 -d 192.168.10.$i -j DNAT \
--to-destination 192.168.0.$i
iptables -t nat -A POSTROUTING -o eth2 -s 192.168.0.$i -j SNAT \
--to-source 192.168.10.$i
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.$i -j SNAT \
--to-source 192.168.10.$i
i=`expr ${i} + 1`
done
;;
stop)
# Zähler für Klasse C Subnetz auf null setzen
i=0
# fwmark Classmark setzen
iptables -t mangle -D PREROUTING -i eth1 -s 192.168.0.2 \
-d 192.168.10.0/24 -j MARK --set-mark 0x1
iptables -t mangle -D PREROUTING -i eth2 -s 192.168.0.0/24 \
-d 192.168.10.0/24 -j MARK --set-mark 0x2
# Für das gesamte Subnetz die D-/ und SNAT Regeln in beide Richtungen
# aufsetzen
while [ "$i" != 256 ]
do
iptables -t nat -D PREROUTING -i eth1 -d 192.168.10.$i -j DNAT \
--to-destination 192.168.0.$i
iptables -t nat -D PREROUTING -i eth2 -d 192.168.10.$i -j DNAT \
--to-destination 192.168.0.$i
iptables -t nat -D POSTROUTING -o eth2 -s 192.168.0.$i -j SNAT \
--to-source 192.168.10.$i
iptables -t nat -D POSTROUTING -o eth1 -s 192.168.0.$i -j SNAT \
--to-source 192.168.10.$i
i=`expr ${i} + 1`
done
;;
*)
echo "Fehler ! Erlaubte Parameter: (start|stop)"
exit 1
;;
esac
exit 0
FIXME: das ist für Julia :-)
FIXME: nmap & co
FIXME: Liste bekannter Penetrationstools (Nessus und co)
FIXME: was ist ein Exploit ?
FIXME: Was ist ein Smurf ?
FIXME: Hier Liste (CERT, Bugtraq etc)
FIXME: Soll man ?
FIXME: Hier die Firewall mit Kommentaren einfügen. Zu klären: Steht die unter der GPL ?
FIXME: Freiwillige vor !
FIXME: Freiwillige vor !
FIXME: Ohhhh jaaaaa, ganz wichtig
FIXME: Hier GPL oder diese andere Textsource Lizens rein
Muss ich wirklich ? ;-)