Neuere Linux-Kernel besitzen von Haus aus Firewall-Funktionen. Man spricht dabei von so genannten Filterketten (Chains). Diese entscheiden anhand vorgegebener Regeln über das Schicksal eines Datenpaketes. Innerhalb des Linux-Kernels gibt es drei vordefinierte Ketten, die Entscheidungen über Datenpakete treffen können: die INPUT-Chain, FORWARD-Chain und OUTPUT-Chain.
Die INPUT-Chain behandelt alle Pakete, die in das System über ein Netzwerk-Interface hereinkommen. Sind die Pakete für das lokale System bestimmt, werden sie nach der Prüfung direkt an die OUTPUT-Chain durchgereicht und anschließend an den lokalen Prozess weitergegeben. Sind die Pakete zum Durchleiten (forwarding) an andere Systeme bestimmt, wird zunächst die FORWARDING-Chain und erst dann die OUTPUT-Chain konsultiert. Pakete für das lokale System prüft der Kernel also ein- oder zweimal, Pakete die an andere Systeme weitergereicht werden, durchlaufen bis zu drei Prüfungen.
Es ist jedoch üblich, lediglich die INPUT- und FORWARDING-Chains als Filter zu nutzen und in der OUTPUT-Chain alle Pakete zu akzeptieren, da man schon bei Eingang des Paketes bzw. bei Überprüfung der Forwarding-Regeln alle Informationen besitzt, um über den weiteren Weg zu entscheiden.
Schematische Darstellung der IPchains-Entscheidungen über
ein Datenpaket
Umfangreiche Regelsätze sind sicherlich nur noch schwer überschaubar, wenn man dafür einzig die Filterketten INPUT, FORWARD und OUTPUT nutzt. ipchains erlaubt aber auch die Definition eigener Ketten und somit die Aufspaltung des Regelwerks in funktionale Einheiten. Hiervon Gebrauch zu machen ist dringend anzuraten, erst Recht, wenn mehrere Personen ein Regelwerk verstehen und betreuen sollen.
Unter Linux gibt es verschiedene Pakete, mit deren Hilfe man die Behandlung von IP-Paketen im Kernel beeinflussen kann. Grundvoraussetzung ist jedoch ein Kernel, der IP-Firewalling zulässt: In 2.2er Kernels sind hierfür die Optionen Network "firewalls", "TCP/IP networking", "IP: firewalling" und "IP: firewall packet logging" zu aktivieren, ab Kernel 2.4.0 ist statt dessen die Option "Network Packet Filtering" zu wählen.
Zur Beeinflussung der Firewall-Regeln für den Kernel gibt es die Dienstprogramme ipfwadm, ipchains und iptables. ipfwadm arbeitet auch mit einem Kernel vor 2.2.0 zusammen. In aktuellen Distributionen wird jedoch zumeist ipchains mitgeliefert, das die Funktionalität und Flexibilität von ipfwadm noch ergänzt. Zudem wurde bei ipchains die Befehlssyntax deutlich vereinfacht.
iptables ist eine Weiterentwicklung von ipchains und sollte mit einem Kernel ab Version 2.4.0 Verwendung finden. Das Beispielskript in diesem Artikel arbeitet jedoch mit ipchains, so wie man es mit einem Kernel 2.2.x nutzen würde, da dies die derzeit verbreitetste Version sein dürfte.
Für die Firewallregeln stehen in einen Linux-Paketfilter folgende Kriterien zur Verfügung:
Die im Folgenden vorgestellen Filterregeln sind im kommentierten Beispiel-Skript unter Benutzung von ipchains als Anweisung zur Filterprogrammierung implementiert. Beispielhaft soll von einen Netzwerk ausgegangen werden, das den Mitarbeitern einer Firma den Zugang zum World-Wide-Web eröffnen und ihnen die Möglichkeit geben will, gegebenenfalls auch Dateien aus dem Internet herunterzuladen. Ein- und ausgehende E-Mails sollen jeweils über ein Secure Server Network (SSN) laufen (auch "Demilitarisierte Zone", DMZ genannt), dessen Server der Internet-Gemeinde zusätzlich verschiedene Dienste (WWW, News und FTP) zur Verfügung stellen. Intranet, SSN und Internet sind über einen multi-homed Host miteinander verbunden, der unter Linux läuft und als Paketfilter fungiert.
Architektur des Beispielnetzwerks
Als erstes sollte man immer Regeln implementieren, die das beliebte IP-Spoofing abwenden. Für die Interfaces eigener Netze ist das völlig unproblematisch:
Analoges gilt für eth2, die Schnittstelle zum Intranet. eth0 benötigt keine eigenen Regeln, da sich die Ablehnung (bekanntermaßen) gefälschter IP-Nummern aus dem Internet aus den Regeln für eth1 und eth2 ergibt.
Der nächste - nicht minder wichtige Schritt - ist das Einfügen der einfachen aber wirkungsvollen Default-Deny-Regel. Nach dem Motto "Es ist alles verboten, was nicht explizit erlaubt ist" lehnt die Firewall zunächst alle Pakete ab (restriktiver Ansatz). Da ein Linux-Paketfilter alle Regeln von oben nach unten abarbeitet, muss man die im Folgenden besprochenen Regeln, die den Zugriff auf bestimmte Dienste erlauben, vor dieser Auffangregel implementieren.
Um den Intranet-Usern Zugriff auf das World-Wide-Web zu ermöglichen, braucht es zwei Regeln:
Das Regelwerk für die E-Mail ist ganz ähnlich aufgebaut, wobei aus- und eingehende Nachrichten immer über das SSN laufen sollen und die Teilnehmer des Intranet nur im SSN Nachrichten abholen dürfen (genaue Umsetzung siehe Skript - Allerdings beziehen sich die eben beschriebenen Filterregeln auf die FORWARD-Chain. Sie implizieren, dass zu prüfende Pakete bereits die INPUT-Chain erfolgreich passiert haben. Die Implementierung des Beispiel-Skripts nutzt hingegen ausschließlich die INPUT-Chain. Es gibt meist verschiedene Wege, um ein Regelwerk erfolgreich umzusetzen.)
Die SYN/ACK-Kombination ist ein taugliches Filtermerkmal bei den WWW-Regeln, stellt jedoch den Administrator des Beispielnetzes vor ein Problem bei FTP. Um den Benutzern FTP zu erlauben sind die genannten Regeln nur bedingt anwendbar: Der Zugriff auf passives FTP ist durch ein analoges Regelwerk für Port 21 (Kommandokanal) und Port 20 (Datenkanal) möglich, nicht aber der Zugriff auf aktives FTP, bei dem der externe FTP-Server einen neuen Datenkanal öffnet. Dazu äußert er einen neuen Verbindungswunsch (üblicherweise) von Port 20 aus. Folgende Regeln wären für aktives FTP erforderlich:
Diese Regeln bzw. die Erlaubnis für aktives FTP gestatten aber auch einem Angreifer vom Internet aus jeden beliebigen hohen Port eines lokalen Rechners zu adressieren; die einzige Voraussetzung ist, dass der Angreifer den Port20 als Quelle verwendet. Dies öffnet trojanischen Pferden Tür und Tor und kann bei unsicher konfigurierten oder infiltrierten Rechnerm im Intranet dazu führen, dass diese ihre Dienste nach außen anbieten.
Hier zeigt sich ein Nachteil von Paketfiltern: Sie schauen nicht tief genug in die übertragenen Pakete, um prüfen zu können, ob nun wirklich FTP "gesprochen" wird oder ob dort vielleicht ein ganz anderes Protokoll abläuft, das auf diesem Port eigentlich nichts zu suchen hat.
Noch drastischer sind die Auswirkungen, wenn der FTP-Server als Source-Port für den Datenkanal nicht auf Port 20 festgelegt sein soll. Will man solche Kommunikation erlauben, so ist der Paketfilter viel zu weit geöffnet. Sicheres FTP ist somit nur möglich, wenn alle Clients und die genutzen Server passives FTP unterstützen, was heute aber in der Regel der Fall ist. Aktives FTP sollte man auf der Firewall daher untersagen.
Weitere grundlegende Regeln sind im Beispiel-Skript beschrieben und kommentiert. Linux bietet jedoch weitaus mehr Möglichkeiten als einfaches Filtern innerhalb der Ketten INPUT, FORWARD und OUTPUT. Auch in Bezug auf das oben genannte Beispielnetzwerk bieten sich weitere Ansatzpunkte um die Sicherheit zu erhöhen.
Bislang hat der Paketfilter Daten einfach weitergereicht, was jedoch in Wirklichkeit nicht funktionieren würde, da weder Intranet noch SSN im Beispielnetz offizielle IP-Adressen verwenden und somit die Datenpakete im Internet nicht geroutet würden. Zur Abhilfe gibt es verschiedene Ansätze, vornehmlich IP-Masquerading und Network Adress Translation (NAT). Eine weitere Möglichkeit wäre der Einsatz von Proxies (auf der Firewall) für jedes gewünschte Protokoll.
NAT beschreibt streng genommen eine Technik, bei der eine beschränkte Anzahl offizieller IP-Adressen zur Verfügung steht und das Gateway (hier in Funktionseinheit mit der Firewall) eine Tabelle verwaltet, die interne, nicht routbare, Adressen bei Bedarf 1:1auf die offiziellen Adressen abbildet. Die Nachteile dieser Technik sind offensichtlich:
IP-Masquerading (oder auch "1: many NAT") wählt einen anderen Lösungsansatz. Hier werden alle internen IP-Nummern hinter einer offiziellen IP-Adresse verborgen. Alle aktuellen Linux-Kernel unterstützen diese Technik und stellen somit eine taugliche Lösung für die Internet-Anbindung des Beispiel-Intranets dar. Es ist allerdings zu beachten, dass einige Prokolle (z.B. FTP) aufgrund ihrer Eigenarten beim IP-Masquerading eine Sonderbehandlung benötigen. Dafür sind zusätzliche Kernel-Module zu laden.
IP-Masquerading wird im Regelwerk einfach durch das Sprungziel MASQ realisiert (siehe Beispiel-Skript). Dies bewirkt gleichzeitig, dass durch eine einzige INPUT-Regel Antwortpakete auf der Firewall akzeptiert und an einen lokalen Prozess zur Demaskierung weitergereicht werden können.
----------Anfang Textkasten----------
#!/bin/sh
#
# Beispiel-Skript zur Beeinflussung der Filterketten des Linux-Kernels
# mit Hilfe des Dienstprogrammes ipchains
#
# **********************************************************************
# ** Dieses Beispiel stellt keine abschließende Paketfilterlösung dar **
# ** und ist nicht zur direkten Übernahme in bestehende Netzwerkumge- **
# ** bungen gedacht. Der Autor sowie die GENIA-SEC übernehmen keiner- **
# ** lei Haftung. **
# **********************************************************************
#
# Hier würde man zunächst die Kernel-Optionen setzen...
# (aus Platzgründen ausgelassen)
#
# Firewall zunächst komplett schließen
#
# Alle Regeln löschen (-F = flush)
ipchains -F input
ipchains -F forward
ipchains -F output
ipmasqadm portfw -f
#
# Default-Regel ist alle Pakete abzulehnen (-P = policy, -l = loggen)
ipchains -P input DENY -l
ipchains -P forward DENY -l
ipchains -P output ACCEPT
#
#
# Konstantendefinitionen (erhöhen die Übersichtlichkeit)
#
# Devices
DEV_WORLD="eth0"
DEV_SSN="eth1"
DEV_INT="eth2"
#
# Networks
NET_WORLD="0/0"
NET_SSN="192.168.100.0/24"
NET_INT="192.168.101.0/24"
#
# Hosts
FW_WORLD="62.152.35.10/32"
FW_SSN="192.168.100.254/32"
FW_INT="192.168.101.254/32"
MAIL_SSN="192.168.100.1/32"
MAIL_INT="192.168.101.1/32"
#
# high Ports
HIGH_PORTS="1025:65535"
#
# absolute IP-Adressen für Port-Forwarding
PF_FIREWALL="62.152.35.10"
PF_MAIL_SSN="192.168.100.1"
#
# IP-Spoofing
#
# Hier wird zunächst mittels -A (add) der input-Kette eine Regel hinzugefügt,
# die besagt, wenn das Interface (-i) die Netzwerkkarte zum SSN ist und die
# Source-Adresse (-s) des eingehenden Paketes nicht (symbolisiert durch ein
# Ausrufezeichen) aus dem entsprechenden Netzbereich stammt, dann springe (-j)
# zur abweisenden Regel (DENY) und protokolliere das Ganze über den syslog-
# Mechanismus (-l). Die zweite Regel schafft dann Sicherheit basierend auf dem
# Interface. Das Ganze wird wiederholt für das zum lokalen Netz gehörende
# Interface.
#
ipchains -A input -i $DEV_SSN -s ! $NET_SSN -j DENY -l
ipchains -A input -i ! $DEV_SSN -s $NET_SSN -j DENY -l
ipchains -A input -i $DEV_INT -s ! $NET_INT -j DENY -l
ipchains -A input -i ! $DEV_INT -s $NET_INT -j DENY -l
#
# (IP-Spoofing-Schutz kann auch über den Kernel mit Hilfe von
# Source Address Verification erfolgen)
#
# Der Einfachheit halber wird nur in der INPUT-chain gefiltert. Alle Pakete,
# die die INPUT-chain passieren, werden ohne weitere Überprüfung geforwardet
# (dies sollte im Echtbetrieb nicht unbedingt so sein - vielmehr nutzt man
# die FORWARD-chain als zweite Prüfungsinstanz). Pakete nach draußen werden
# zudem maskiert (Sprungziel MASQ anstatt ACCEPT), da sie ansonsten nicht
# über eine offizielle IP-Adresse verfügen.
#
# Forwarding INT-WLD, INT-SSN, SSN-WLD, SSN-INT
ipchains -A forward -p tcp -i $DEV_WORLD -s $NET_INT -j MASQ
ipchains -A forward -p tcp -i $DEV_SSN -s $NET_INT -j ACCEPT
ipchains -A forward -p tcp -i $DEV_WORLD -s $NET_SSN -j MASQ
ipchains -A forward -p tcp -i $DEV_INT -s $NET_SSN -j ACCEPT
#
# Wichtig: Für Antwortpakete aus dem Internet in das lokale Netz ist keine
# Forwarding-Regel erforderlich. Masquerading stellt einen lokalen Prozess dar,
# d. h. eingehende Antwortpakete müssen in der INPUT-chain geprüft werden und
# gelangen schließlich zu einem lokalen Prozess, der sie entsprechend demaskiert
# und weiterreicht.
#
# WWW für das Intranet
# Alle tcp-Pakete (-p für protocol) von innen nach außen mit einer beliebigen
# IP-Adresse als Ziel (-d für destination) werden durchgelassen, sofern ihr
# Zielport 80 ist (bei korrekt gepflegter /etc/services kann für 80 auch das
# Schlüsselwort www oder http eingetragen werden). Das ACK-Flag bleibt bislang
# unberücksichtigt, da von innen nach außen ein Verbindungsaufbau durchaus
# erwünscht ist.
#
ipchains -A input -p tcp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $NET_WORLD 80 \
-j ACCEPT
#
# Genau genommen werden nun auch WWW-Anfragen vom lokalen Netz in die SSN
# durchgelassen. Man müsste dies ggf. durch eine vorgeschaltete DENY-Regel
# unterbinden.
#
# Die Antwortpakete werden nun an die Linux-Firewall zurückadressiert, wo sie
# dann wieder demaskiert und an den Client durchgereicht werden. Allerdings
# existiert bislang noch keine Input-Regel, die der Firewall erlaubt diese
# Pakete entgegenzunehmen. Diese wird nun eingefügt:
#
ipchains -A input -p tcp -i $DEV_WLD -s $NET_WORLD 80 -d $FW_WORLD $HIGH_PORTS \
! -y -j ACCEPT
#
# Diese Regel erlaubt eingehende TCP-Pakete von außen an die Firewall (aber
# nur die "hohen Ports"), sofern es sich um Antwortpakete handelt. Wünsche
# für einen Verbindungsaufbau (SYN=1, ACK=0, FIN=0) werden abgelehnt (! -y).
#
# FTP für das Intranet, erlaubt wird nur passives FTP
#
ipchains -A input -p tcp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $NET_WORLD 21 \
-j ACCEPT
ipchains -A input -p tcp -i $DEV_WLD -s $NET_WORLD 21 -d $FW_WORLD $HIGH_PORTS \
! -y -j ACCEPT
#
# dann der Datenkanal
#
ipchains -A input -p tcp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $NET_WORLD 20 \
-j ACCEPT
ipchains -A input -p tcp -i $DEV_WLD -s $NET_WORLD 20 -d $FW_WORLD $HIGH_PORTS \
! -y -j ACCEPT
#
# nicht vergessen: das notwendige Kernel-Modul
#
insmod ip_masq_ftp
#
# E-Mail
# eingehende Mail an den Mail-Server in der SSN weiterleiten
# (genutzt wird ipmasqadm with port-forwarding support, die Syntax ist der
# von ipchains sehr ähnlich)
#
ipmasqadm portfw -a -P tcp -L $PF_Firewall 25 -R $PF_MAIL_SSN 25
#
# Port-Forwarding funktioniert nur, wenn die Pakete selbst auch angenommen
# werden. Also das bekannte Regelwerk auch für Mail verwenden. Allerdings muss
# auch der Wunsch nach einem Verbindungsaufbau akzeptiert werden.
#
ipchains -A input -p tcp -i $DEV_WLD -s $NET_WORLD $HIGH_PORTS -d $FW_WORLD 25 \
-j ACCEPT
ipchains -A input -p tcp -i $DEV_SSN -s $MAIL_SSN 25 -d $NET_WORLD $HIGH_PORTS \
! -y -j ACCEPT
#
# Der Mail-Server der SSN muss auch selbst Mail versenden dürfen sowie
# Mail vom Intranet zum Versand entgegennehmen
#
ipchains -A input -p tcp -i $DEV_SSN -s $MAIL_SSN $HIGH_PORTS -d $NET_WORLD 25 \
-j ACCEPT
ipchains -A input -p tcp -i $DEV_WORLD -s $NET_WORLD 25 \
-d $FW_WORLD $HIGH_PORTS ! -y -j ACCEPT
#
ipchains -A input -p tcp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $MAIL_SSN 25 \
-j ACCEPT
ipchains -A input -p tcp -i $DEV_SSN $MAIL_SSN 25 -d $NET_INT $HIGH_PORTS \
! -y -j ACCEPT
#
# Der Mail-Server soll den internen Clients Mail-Abholen per POP3 erlauben.
#
ipchains -A input -p tcp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $MAIL_SSN 110 \
-j ACCEPT
ipchains -A input -p tcp -I $DEV_SSN -s $MAIL_SSN 110 -d $NET_INT $HIGH_PORTS \
! -y -j ACCEPT
#
# DNS (Domain Name System)
# (es will ja niemand immer nur IP-Nummern als URL eingeben ;-)
#
# ausgehende Anfragen
#
ipchains -A input -p udp -i $DEV_INT -s $NET_INT $HIGH_PORTS -d $NET_WORLD 53 \
-j ACCEPT
ipchains -A input -p udp -i $DEV_SSN -s $NET_SSN $HIGH_PORTS -d $NET_WORLD 53 \
-j ACCEPT
#
# Forwarding und Maskerade für udp, INT-WLD, SSN-WLD
#
ipchains -A forward -p udp -i $DEV_WLD -s $NET_INT -j MASQ
ipchains -A forward -p udp -i $DEV_WLD -s $NET_SSN -j MASQ
#
# eingehende Antworten
#
ipchains -A input -p udp -i $DEV_WLD -s $NET_WORLD 53 -d $FW_WORLD $HIGHPORTS \
-j ACCEPT
#
# Die Auffang-Regeln (sicher ist sicher)
ipchains -A input -j DENY -l
ipchains -A forward -j DENY -l
Anmerkung: In einer korrekt gesicherten Umgebung würde der SSN- Mail-Server nur mit dem Mail-Server des genutzten Providers kommunizieren oder man würde ggf. eine etwas andere Firewall-Struktur wählen. Ähnliches gilt für den DNS-Server. Die vorliegenden Regeln sollen lediglich zur Verdeutlichung der Funktionsweise eines Paketfilters unter Linux dienen. IPchains bietet viele Möglichkeiten, die dargestellte Schreibweise zu verkürzen, hierauf wurde aber bewusst verzichtet. Ebenso haben wir aus Gründen der Übersichtlichkeit auf die Darstellung der Regeln zur Behandlung von icmp-Paketen verzichtet. Das Beispiel-Netzwerk wäre demnach bislang nicht zur Nutzung von Kommandos wie PING oder TRACEROUTE berechtigt. Genausowenig würden Fehlermeldungen nicht erreichbarer Internetseiten an den aufrufenden Client weitergemeldet. Bitte immer daran denken: Es ist nur ein Beispiel!
----------Ende Textkasten----------
Die Verbindungen in das Internet sind somit eingerichtet. Die SSN-Server und somit auch der Mail-Server sind in Ermangelung offizieller IP-Adressen aber noch nicht von außen erreichbar. Auch hier kann Linux jedoch mit einem Trick aushelfen. Man bedient sich des so genannten Port-Forwarding, d.h. die Firewall nimmt Verbindungswünsche auf einem bestimmten Port entgegen und reicht diese zur eigentlichen Beantwortung an einen festgelegten internen Host weiter.
Für das vorliegende Beispiel bedeutet dies, dass die Firewall Pakete an Port25 entgegennimmt und an den Mail-Server im SSN weiterreicht, der dann mittels IP-Masquerading ins Internet antworten kann.
Port-Forwarding lässt sich mithilfe verschiedener Dienstprogramme realisieren, die sich ebenfalls in das Regelwerk einbinden lassen (u.a. ipportfw, ipmasqadm, ipautofw, redir und udpred). Es sollten heute aber nur noch ipportfw und "ipmasqadm with portfw support" Verwendung finden. Vom Einsatz der älteren Tools ist abzuraten, da diese die Stabilität eines Linux-Systems negativ beeinflussen können. Port-Forwarding sollte man mit einiger Vorsicht betrachten und auf ein Minimum beschränken, da es gewissermaßen gewünschte Löcher in die Firewall reißt. Es stellt zwar kein Risiko für die Firewall selbst dar, gefährdet jedoch den Host, an die Pakete weitergereicht werden. Auf die Rechnersicherheit dieses Systems ist besonders zu achten.
Ein Paketfilter kann zwar über den Werdegang eines Paketes
entscheiden, nicht aber seinen Inhalt prüfen. Zwar ist der
Linux-Kernel gegen einige Attacken von Haus aus immun (z.B. Ping of
Death), andere Schutzmechanismen muss der Administrator jedoch
explizit einrichten, da sie per Default deaktiviert sind. So
lässt sich z.B. ein Schutz vor einer Attacke durch
fragmentierte IP-Pakete durch echo "1" >
/proc/sys/net/ipv4/ip_al ways_defrag
erreichen, sofern man
die grundsätzliche Unterstützung dieser Funktion in den
Kernel eingebunden hat.
Linux lässt sich hervorragend als Paketfilter einsetzen, sofern man sich von der etwas unkomfortablen Konfiguration nicht abschrecken lässt (es gibt jedoch auch einige X-Tools zur Verwaltung des Regelwerks). Betrachtet man allein den Anschaffungspreis, so gibt es in diesem Segment wohl keine ähnlich flexible Alternative.
Neben der einfachen Erstellung von Filterregeln und der Nutzung von Kernel-Optionen finden Interessierte im Internet auch deutlich komplexere und zum Teil trotzdem (zumindest für den nicht-kommerziellen Gebrauch) kostenfreie Komplettlösungen wie zum Beispiel das TIS Firewall Tool Kit oder die SOCKS Proxy-Lösung. All diesen Lösungen ist jedoch gemein, dass sie ein gehöriges Maß an Einarbeitung erfordern und nicht trivial zu installieren sind. Man kann das allerdings auch als Vorteil sehen, da der Administrator sich zunächst einmal mit seinem System auseinanderzusetzen muss und nicht einfach Regeln zusammenklicken kann.
Bodo Meseke ist IT-Security Consultant bei der GENIA-SEC IT-Sicherheitsmanagement GmbH
© SecuMedia-Verlags-GmbH, D-55205 Ingelheim,
KES 4/2000, Seite 75