Vorträge - Firewalls
Firewalls unter Linux
von Thomas Avieny (t_avieny@informatik.uni-kl.de),
Klaus Knopper (knopper@unix-ag.uni-kl.de)

Es werden die grundsätzlichen Konzepte und Ideen hinter Firewalls dargestellt. Anhand von Beispielen wird auf die Vor- und Nachteile der verschiedenen Ansätze eingegangen. Außerdem werden die Möglichkeiten beleuchtet, die Linux hier dem Anwender zur Verfügung stellt.

Inhalt

Theorie
    Warum werden Firewalls benötigt?
    Grundsätzliche Überlegungen
    Paketfilter (Screening Router)
    SOCKS-Server
    Application-Level Gateways
    Beurteilung von Firewalls
Konfigurationsbeispiele unter Linux
    Voraussetzungen
        Ausstattung
        Festlegungen
    ipchains
        Forwarding
            Kernel IP-Forwarding
            Default-Policies
            Masquerading
        Paketfilter
            Default-Policies
            Forwarding für interne Netzwerkadressen erlauben
            Anti-Spoofing und Verbindungaufbau nur in eine Richtung
            Zugriff auf gewünschte Dienste erlauben
        Umleitung (redirect) auf lokale Ports
    Nachwort
    Literatur und Links

Theorie

Warum werden Firewalls benötigt?

Heute besteht häufig die Notwendigkeit ein firmeneigenes Netz mit der Außenwelt zu verbinden. Dabei bestehen für jeden Rechner innerhalb des eigenen Intranet Risiken wie Attacken oder Datendiebstahl bzw. Datenverlust. Somit ist es durch gezielte Angriffe von außerhalb möglich, den (Rechner-)Betrieb lahmzulegen, aber auch an firmeninterne, sensible Daten zu gelangen. Verhindern lässt sich dies mit Hilfe von sogenannten Firewalls. Allerdings sind Firewalls auch kein Allheilmittel, sondern bieten nur einen gewissen Schutz und müssen an die jeweiligen Bedürfnisse angepasst und dauerhaft betreut werden.

Grundsätzliche Überlegungen

Im allgemeinen Sprachgebrauch bezeichnet man mit einem Firewall einen einzelnen Rechner, der als Schnittstelle Intranet und Außenwelt verbindet und den ein- und ausgehenden Datenfluss überwacht und gegebenenfalls filtert bzw. blockiert. Dazu muss entschieden werden, ob der Firewall eher restriktiv (alles verbieten, was nicht ausdrücklich erlaubt wird) oder freizügig (alles erlauben, was nicht explizit verboten wird) gestaltet werden soll. Grundsätzlich gibt es verschiedene Konzepte, um auf ein- und ausgehende Aktivitäten Einfluss zu nehmen. Jedes Konzept stellt einen Kompromiss zwischen Sicherheit und Zugänglichkeit dar. Dies zeigt sich daran, dass ein Konzept transparent, und somit auch komfortabel für den Anwender, oder sicher ist, was sich meist in zusätzlichen Passwortabfragen äußert.

Paketfilter (Screening Router)

Paketfilter (engl. Screening Router) stellen das einfachste Firewall-Konzept dar, indem sie jedes einzelne Paket untersuchen und nach bestimmten Kriterien weiterleiten oder abblocken. Dazu verwenden sie Informationen aus dem IP- und TCP-Header der einzelnen Pakete. In erster Linie sind das Absender- und Empfängeradresse, Absender- und Empfängerport sowie der Pakettyp, also Informationen, die der Transportschicht des Internet-Schichten-Modells entsprechen. Um einen Paketfilter zu erzeugen werden die Kriterien in sogenannte Regeln gefasst und diese später der Reihe nach bearbeitet. Damit wird es möglich, den Datenfluss von bzw. zu bestimmten Rechnern zu kontrollieren. Über die Portnummern können verschiedene Dienste/Programme berücksichtigt werden.

Screening Router sind für den Anwender völlig transparent, d.h. im Normalfall merkt er nichts von einem solchen Filter. Allerdings bieten sie auch nur einen sehr einfachen Schutz. Es ist beipielsweise nicht möglich, sogenannte "flooding attacks" (viele kurz aufeinander geschickte Pakete) zu erkennen. Darüber hinaus ist die Filterliste anfällig für Fehler und kann nur von Administratoren mit genauen Kenntnissen erstellt werden. Die wichtigste Einschränkung ist jedoch, dass sich praktikabel gewisse Dienste und Programme nur für alle oder keinen Benutzer zugänglich machen lassen!

SOCKS-Server

Mit Hilfe von SOCKS-Servern wird es nun möglich, Dienste bzw. Programme nur für bestimmte Benutzer zugänglich zu machen. Ein vollständiges SOCKS-System besteht aus dem eigentlichen SOCKS-Server der auf dem Bastion-Host, d.h. dem Firewall-Rechner, installiert wird, sowie einer Bibliothek auf jedem Client. Die zu benutzenden Programme müssen alle angepasst werden, was allerdings durch das einheitliche Protokoll kein hoher Aufwand ist. Die zusätzliche Funktionalität wird hier durch eine zusätzliche Passwortabfrage und somit einem gewissen Komfortverlust erkauft. Außerdem ist der Aufwand gegenüber Paketfiltern natürlich höher!

Mit SOCKS-Servern ist es immer noch nicht möglich, bestimmte Aktionen oder Befehle einzelner Programme, d.h. auf Anwendungsebene, zu erlauben bzw. zu verbieten.

Application-Level Gateways

Durch Application-Level-Gateways wird es nun möglich, wirklich jede Aktion eines Programms zu kontrollieren. Dazu wird allerdings für jede Applikation ein eigener, sehr spezieller Server benötigt, der die entsprechende Funktionalität bietet. Somit benutzt jeder dieser Server ein eigenes Protokoll, das die Kommandos des Programmes berücksichtigt. Diese Lösung bietet damit auch den besten Schutz, ist allerdings am aufwendigsten.

Beurteilung von Firewalls

Firewalls sind zwar kein Allheilmittel, bieten bei sinnvoller Anwendung aber schon einen brauchbaren Schutz. Außerdem erleichtern sie den Aufwand gegenüber Lösungen für jeden einzelnen Rechner ganz beträchtlich, bieten sie doch eine zentralisierte Stelle für Installation, Konfiguration und Administration.

Zu beachten ist weiterhin:

  • Ein Firewall setzt ein sicheres Betriebssystem vorraus, außerdem sollte nur Firewall-Software auf diesem Rechner installiert sein!
  • Durch die gleichzeitige Verwendung und Kombination der verschiedenen Systeme kann die Sicherheit gesteigert werden.
  • Firewalls bieten nur einen sehr eingeschränkten Schutz gegenüber Viren und Trojanischen Pferden.
  • Schon ein einziges Modem innerhalb des Intranet kann einen noch so sicheren Firewall umgehen!

Konfigurationsbeispiele unter Linux

Der Linux-Kernel unterstützt bereits ohne Zuhilfenahme von Daemon-Prozessen statisches Routing, IP-Forwarding, IP-Paketfilter, IP-Accounting, Port-Umleitung und Masquerading (auch oft im Zusammenhang mit NAT - Network Address Translation - genannt). Diese Eigenschaften werden in Form von kernelinternen Tabellen bzw. Ketten von Regeln (Chains) konfiguriert. Zur Verwaltung dieser Regeln dienen die Programme ipfwadm (Kernel bis 2.0.36) und ipchains (Kernel ab 2.2.0). ipchains bietet gegenüber ipfwadm durch ein neues Konzept von Regel-Verkettungen (siehe Skizze) eine höhere Flexibilität sowie einige neue Optionen, die erst mit den neuen Kernels verwendet werden können. Im Folgenden werden Konfigurationsbeispiele mit ipchains betrachtet, wovon die meisten - mit abgewandelter Syntax - prinzipiell auch auf ipfwadm übertragbar sind.

Voraussetzungen

Ausstattung

Für die folgenden Beispiele müssen einige Mindestanforderungen an das Hostsystem erfüllt sein.

  • Linux ab Kernel 2.2,
  • Mehrere Netzwerkinterfaces (z.B. zwei Netzwerkkarten oder eine Netzwerkkarte plus Modem/ISDN),
  • TCP/IP-Support im Kernel (Standard)
  • IP-Forwarding-Support im Kernel,
  • IP-Firewall-Support im Kernel,
  • evtl. IP-Masquerading-Support im Kernel und spezielle Masquerading-Module,
  • installierte Programmpakete ipfwadm bzw. ipchains.

Die ipfwadm/ipchains-Pakete sind üblicherweise Standard-Ausrüstung in der Contrib der jeweiligen Linux-Distribution und als freie Software inklusive Quelltext erhältlich.

Falls der Kernel keinen Firewall-Support hat, muss er neu übersetzt werden. Hierzu sind bei make menuconfig die Optionen Network firewalls, IP: firewalling und bei Masquerading IP: always defragment sowie möglichst alle Masquerading-Optionen im Menüpunkt Networking options auszuwählen.

Festlegungen

Der Einfachheit halber sei in folgenden Beispielen angenommen, dass ein internes Netzwerk mit IP-Adressen im Bereich 192.168.1.1 bis 192.168.1.254 vorhanden sei, wobei der als Router/Firewall einzusetzende Linux-Rechner auf der Netzwerkkarte eth0 mit der Adresse 192.168.1.254 konfiguriert und mit dem internen Netz verbunden ist. Als externe Schnittstelle des Linux-Rechners wird im Beispiel ein analoges Modem verwendet, das vom Provider über PPP eine dynamische IP-Adresse zugewiesen bekommt, über die es Daten ins Internet schicken und vom Internet entgegennehmen kann. Da die IP-Adresse von ppp0 nicht konstant ist, müssen die ipchains-Regeln entsprechend flexibel ausgelegt werden, da sonst bei jedem Dialout die Konfiguration der Filter- und Forwardingregeln geändert werden müsste.

 

ipchains

Für ein- und ausgehende IP-Pakete (TCP, UDP und ICMP) können Regeln definiert und miteinander verkettet werden. Bei einer Kette von Regeln (Chain 1 in der Skizze) wird nacheinander überprüft, ob auf ein Paket die angegebenen Eigenschaften (Source/Destination-Adresse, Source/Destination-Port, Art des Paketes, Interface) zutreffen. Treffen die von einer Regel angegebenen Eigenschaften zu, wird zu einer vordefinierten Behandlung des Paketes (Tabelle) oder in eine für diesen Fall definierte weitere Kette von Regeln (Chain 2 in der Skizze) verzweigt.

Die vordefinierten und vom Kernel direkt umsetzbaren Behandlungen eines IP-Paketes, auf das eine Regel zutrifft, sind:

ACCEPTAkzeptieren des Paketes
DENYDas Paket wird ohne Rückmeldung an den Absender verworfen (dieser bekommt eventuell einen Timeout, wenn es sich um ein TCP-Paket handelte)
REJECTDas Paket wird verworfen und der Absender erhält per ICMP eine Rückmeldung, dass die Verbindung abgebrochen wurde. (Dies führt auf der Absender-Seite zu der bekannten Meldung "connection refused", die auch im Normalfall auftritt, wenn auf dem Zielport kein Server-Dienst läuft.)
MASQDas Paket wird nach Umschreiben der Source-Adresse in die des Routers an den Zielhost weitergeleitet
REDIRECTDas Paket wird auf eine andere IP-Adresse/Port umgeleitet
RETURNRücksprung zur nächsten Regel in der vorigen Regelkette

Folgende Chains sind vordefiniert:

inputRegeln für ankommende Pakete
outputRegeln für abzuschickende Pakete
forwardRegeln für weiterzuleitende Pakete
neuer_nameBenutzerdefinierte Regeln, die in die bereits gesetzten eingeklinkt werden können (z.B. Chain 2 in der obigen Skizze)

Forwarding

Kernel IP-Forwarding

Per Default ist bei den älteren Kernels 2.0.x das Forwarding von IP-Paketen zwischen Netzwerkinterfaces aktiviert, d.h. der Kernel leitet automatisch aufgrund von Source- und Destination-IP eines Paketes die Daten an die entsprechenden Netze, sofern über seine lokalen Interfaces erreichbar, weiter.

Mit dem Kommando

   echo 0 > /proc/sys/net/ipv4/ip_forward

lässt sich das Forwading, unabhängig von gesetzten Firewall-Regeln oder Routing-Tabellen, deaktivieren. mit

   echo 1 > /proc/sys/net/ipv4/ip_forward

lässt es sich aktivieren.

Default-Policies

Wenn noch keine Regeln definiert wurden oder nach Aufruf von

   ipchains -F input
   ipchains -F output
   ipchains -F forward

sind üblicherweise die Default-Behandlungen alle gleich ACCEPT, d.h. es werden Pakete in ein- und ausgehender Richtung akzeptiert und je nach Herkunft- und Zieladresse weitergeleitet. Daher genügt es, mit route die statischen Routes und das Defaultgateway zu setzen, um einen Linux-Rechner als Router zu betreiben. Wird dynamisches Routing verwendet, so müssen die Kernel-Routingtabellen durch einen Daemon (routed, gated) aktualisiert werden.

 

Masquerading

Ein privates Netz mit den üblicherweise nicht gerouteten, reservierten IP-Adressen 192.168.1.x soll über einen Linux-Rechner Zugang zum Internet erhalten. Durch Masquerading ist es möglich, den Netzzugang über die Modem-Schnittstelle des Linux-Rechners (ppp0) gemeinsam für alle Rechner im privaten Netz zu nutzen. Die Rechner im privaten Netz müssen hierfür lediglich die ins interne Netz zeigende IP-Adresse 192.168.1.254 des Linux-Rechners als Default-Gateway eintragen. Auf dem Linux-Rechner wird mit der Regel

   ipchains -A forward -s 192.168.1.0/24 -d 0/0 -j MASQ

das IP-Masquerading für das private Netz aktiviert. Erkennt der Linux-Kernel ein IP-Paket, das aus dem internen Netz stammt und eine Zieladresse im externen Netz besitzt, so merkt er sich die Adresse des sendenden Rechners, ersetzt diese im IP-Paket durch seine eigene und leitet das Paket über sein externes Interface ppp0 weiter. Der externe, angerufene Host sieht also nur die derzeit weltweit gültige externe IP-Adresse des Linux-Rechners. IP-Pakete, die anschließend vom angerufenen Host auf den Source-Port des vermeintlichen "Anrufers" zurückgeschickt werden, werden vom Linux-Router so umgeschrieben, dass als Zieladresse wiederum die Adresse des Rechners im internen Netz eingetragen wird, der die Verbindung ursprünglich initiiert hat. Auf diese Weise entsteht über den masqueradenden Linux-Router eine bidirektionale Verbindung zwischen den beiden Rechner im internen und externen Netz.

Dieses Feature hat den Vorteil, dass (fast) alle Dienste des Internet uneingeschränkt aus dem Intranet genutzt werden können, sofern sie keinen Verbindungsaufbau in Rückrichtung erfordern. Ein direkter Verbindungsaufbau aus dem externen ins interne Netz ist nicht möglich, da der IP-Bereich des internen Netzes vor dem externen "versteckt" wird. Im Zusammenspiel mit den weiter unten erwähnten Anti-Spoofing-Regeln ist dies bereits eine sehr komfortable Lösung, um in vielen Fällen ausreichende Sicherheit für das interne Netz zu gewährleisten.

Dienste wie FTP, die einen Verbindungsaufbau aus dem externen ins interne Netz erfordern (ftp-data), sind mit Masquerading allein zunächst problematisch. Hierfür gibt es jedoch Lösungen mit Hilfe von zusätzlichen Kernel-Modulen, die dienstspezifisch bei einer bereits bestehenden Steuerverbindung Pakete zu Ports des dienstanfordernden Rechners im internen Netz weiterleiten. Beispiel:

   modprobe ip_masq_ftp
   modprobe ip_masq_irc
   modprobe ip_masq_raudio

Eine weitergehende Kontrolle der im Kernel implementierten Masquerading-Funktionen bietet das Utility ipmasqadm, das ebenso wie ipchains zur Standardausrüstung eines Linux-Routers gehört.

Paketfilter

Default-Policies

Zum Betrieb eines komplexeren Firewalls - vor allem dann eingesetzt, wenn das interne Netz nicht per Masquerading versteckt, sondern mit weltweit gültigen IP-Adressen versehen wird - gibt es je nach Sicherheitsbedarf in der Praxis zwei Fälle:

Fall 1:
Die Default-Policy für die Annahme/Weiterleitung von IP-Paketen bleibt auf ACCEPT und der Zugriff auf unerwünschte Ports wird gezielt gesperrt.
Fall 2:
Zunächst wird der gesamte durch den Linux-Router gehenden Netzwerkverkehr gesperrt und dann gezielt für bestimmte Adressen und Ports wieder geöffnet.

Im Fall 1 wird, falls beispielsweise der Telnet-Dienst vom externen ins interne Netz gesperrt werden soll, folgende Regel angewendet:

   ipchains -I input -i ppp0 -d 192.168.1.0/24 23 -p tcp -j DENY

Vom (Modem-)Interface ppp0 kommende TCP-Pakete mit Zieladresse im internen Netz und Zielport 23 (Telnet) werden hiermit verworfen. Ein telnet zum Firewall-Rechner selbst wäre hierbei aber immer noch möglich, da dessen externe Adresse nicht mit der angegebenen Maske 192.168.1.0/24 übereinstimmt!

Im Fall 2 wird im Beispiel die Default-Policy für die Input-Regeln auf DENY gesetzt. Hierdurch werden sämtliche ankommenden IP-Pakete verworfen, wenn keine der noch zu definierenden ipchains-Regeln greift.

  ipchains -P input DENY

(Hinweis: Man sollte dies aus verständlichen Gründen nicht über das Netz versuchen, sondern an der Konsole oder mit einem vorher ausgiebig getesteten Script arbeiten. Falls Folgeregeln zum Wiederöffnen von Ports fehlschlagen, sperrt man sich sonst selbst aus.)

Die meisten der im Folgenden kommentierten ipchains-Regeln beziehen sich auf Fall 2.

Forwarding für interne Netzwerkadressen erlauben

Pakete aus dem internen Netz sollen den Firewall passieren dürfen.

  # Lokale Verbindungen erlauben (X-Window, lokale daemons etc.)
  ipchains -A input -i lo -j ACCEPT
  # Privates Netz hinter eth0 hat uneingeschränkten Zugriff
  ipchains -A input -i eth0 -j ACCEPT
 

Anti-Spoofing und Verbindungaufbau nur in eine Richtung

Obwohl die Netzwerkadressen 192.168.x.x normalerweise nicht von Providern geroutet werden (sollten), ist ein Angriff möglich, in dem der Angreifer vortäuscht, seine IP-Pakete stammten aus dem internen Netz und dürften wegen der oben behandelten Masquerading-Regeln den Linux-Router passieren. Hier muss der Linux-Firewall erkennen, dass die Pakete nicht aus dem internen Netz stammen, sondern aus dem externen Netz über das Interface ppp0 geschickt wurden, und muss diese verwerfen.

   ipchains -A input -i ppp0 -s 192.168.1.0/24 -j DENY

Diese Regel sollte vor denjenigen Regeln stehen, die Verbindungen erlauben.

Zugriff auf gewünschte Dienste erlauben

Nach den oben definierten Regeln können bereits Pakete aus dem internen Netz das externe Netz erreichen. Nun muss ein "Rückweg" ermöglicht werden, wobei darauf geachtet werden muss, dass hierdurch keine Angriffspunkte entstehen. Beispielsweise ist es günstiger, auf dem Firewall einen Caching Nameserver zu betreiben, der vom internen Netz aus abgefragt werden kann, als den Zugriff auf externe Nameserver (und den Rückweg!) für das interne Netz zu erlauben.

Im folgenden Beispiel wird das Entgegennehmen von WWW-Daten (TCP, Port 80) erlaubt, jedoch nur, falls die Verbindung aus dem internen Netz initiiert wurde.

   ipchains -A input -i ppp0 -s 0/0 80 -p tcp ! -y -j ACCEPT

Diese Regel funktioniert aufgrund der Tatsache, dass beim Aufbau von TCP-Verbindungen ein Handshake wie unten abgebildet erfolgen muss.

Im ersten TCP-Paket beim Verbindungsaufbau von Host A zu Host B ist das Synchronize-Flag gesetzt. In der Antwort des angerufenen Host B sind sowohl Synchronize als auch Acknowledge gesetzt, woraufhin Host A mit dem Senden eines weiteren Acknowledge und den eigentlichen Daten beginnen kann. Es genügt also, diejenigen Pakete auszufiltern, die lediglich SYN gesetzt haben, um den Aufbau einer TCP-Verbindung zu verhindern. Beim UDP-Protokoll besteht diese Möglichkeit nicht.

 

Umleitung (redirect) auf lokale Ports

Folgende ipchains-Regel leitet alle Verbindungen, die vom internen Netz aus an externe WWW-Server gehen, auf den Port 3128 des Firewalls um, auf dem ein Squid-Cache läuft. Der Linux-Firewall wird hierdurch zu einem transparenten (von den Clients unbemerkten) Proxy.

   ipchains -A input -i eth0 -d 0.0.0.0/0 80 -p tcp -j REDIRECT 3128

Neben dem nützlichen Effekt, dass unabhängig von der Browser-Einstellung immer der Cache des Linux-Gateways verwendet wird, kann man sich so das Zulassen direkter WWW-Verbindungen auf Port 80 zwischen Rechnern im internen und externen Netz ersparen. Der Firewall selbst muss natürlich so eingestellt werden, dass er entsprechende WWW-Daten von Port 80 externer Rechner entgegennimmt.

Ein weiterer Anwendungsfall ist die Umleitung einer Verbindung auf einen lokalen Port, auf dem ein verschlüsselnder Proxy läft, der eine für den Benutzer transparente Verbindung zu einer Gegenstelle herstellt. Die Daten werden auf der Strecke zwischen den beiden Proxies verschlüsselt übertragen, der Anwender erhät auf seiner Seite jedoch die vom Firewall bereits entschlüsselte Fassung, ohne sich um technische Details der abhörsicheren Übertragung kümmern zu müssen.

Nachwort

Die hier vorgestellten ipchains-Regeln dienen nur zur Veranschaulichung und sind zum Betrieb eines auf eine konkrete Anwendung bezogenen Firewalls in den wenigsten Fällen ausreichend. Da Firewalls sehr individuell auf den Benutzerkreis abgestimmt werden müssen, ist es nicht möglich, ein auch nur annähernd allgemeingültiges Init-Shellskript mit ipchains-Regeln für einen Firewall anzugeben, auch wenn dies bei vielen Distributionen mittlerweile versucht wird. Zur Konfiguration eines Firewalls und zum komfortablen Aufstellen der Regeln gibt es jedoch diverse graphische Tools, mit denen das Einrichten eines Firewalls ohne genaue Kenntnis der Syntax von ipchains oder Kenntnis von Abläufen im Kernel möglich gemacht werden soll. Links hierzu sind u.a. auf den unten angegebenen Web-Seiten zu finden.

Literatur und Links


Zusammenstellung Copyright © 1999 LinuxTag-Team