IPsec-Verkehr war beim Linux-Kernel 2.6 bisher weitaus schwieriger zu filtern als noch unter 2.4. Seit Ende März 2006 klappt mit den aktuellen Versionen von Kernel und IPtables das Zusammenspiel endlich wieder reibungslos: Das Policy-Match und ein Patch von McHardy machen's möglich.
Admins gelten normalerweise nicht als stockkonservativ. Dennoch scheuen sie sich oft, Linux-basierte VPN-Gateways auf Kernel 2.6 zu aktualisieren. Grund: Der Netkey-IPsec-Implementierung [1] des Kernels 2.6 fehlt die virtuelle Schnittstelle »ipsec0«. Freeswan [3] hatte dieses Interface für Linux 2.4 eingeführt und damit einfache Filterung und Adressenumsetzung (NAT) des IPsec-Verkehrs erlaubt. Abbildung 1 zeigt den einleuchtend einfachen Datenfluss.

Abbildung 1: Der Linux-Kernel 2.4 verfügt über virtuelle »ipsecX«-Netzwerkkarten. Über dieses Interface läuft der Verkehr im Klartext und bleibt vom IPsec-verpackten Teil getrennt.
Folglich war es leicht, für jeden Verkehrstyp die passenden Firewallregeln [2] zu definieren. Das Beispiel nutzt eine interne Netzwerkkarte »eth0« und eine externe »eth1«. Zusätzlich implementiert Freeswan ein virtuelles Netzwerkdevice »ipsec0«. Die Pakete, die der Kernel zwischen »eth0« und »ipsec0« weiterleitet, sind beim Transport über das Internet durch den IPsec-Tunnel geschützt. Pakete, die Linux zwischen den Netzwerkkarten »eth0« und »eth1« transportiert, gehen auch im Klartext durch das Internet. Möchte der Administrator Telnet nur über das VPN erlauben, genügen die Regeln in Listing 1.
|
Listing 1: Virtuelles |
|---|
01 iptables -P FORWARD DROP 02 iptables -A FORWARD -m state ESTABLISHED,RELATED -j ACCEPT 03 iptables -A FORWARD -p tcp --dport 23 -m state --state NEW -i eth0 -o ipsec0 -j ACCEPT |
Virtuelles Interface
Die erste Zeile setzt die Default-Policy in der Forward-Kette auf »DROP«. Die Firewall verwirft fortan alle Pakete, die nicht explizit erlaubt sind. Zeile 2 akzeptiert alle Pakete, die Netfilter als Teil einer aufgebauten Verbindung erkennt. Die dritte Zeile erlaubt Pakete mit Zielport 23 (Telnet), wenn sie eine neue Verbindung aufbauen, das VPN-Gateway über die interne Netzwerkkarte erreichen und sich ans virtuelle Interface »ipsec0« richten. IPsec verschlüsselt in Wirklichkeit alle Pakete, die über »ipsec0« den Rechner scheinbar verlassen, und sendet sie über »eth1« ans ferne VPN-Gateway.
Das Problem: Die virtuellen Schnittstellen stehen für Kernel 2.6 nur noch mit einem Patch zur Verfügung. Das KLIPS-Patch [4] enthält den von Freeswan portierten IPsec-Stack einschließlich der virtuellen Netzwerkkarten und verwendet nicht mehr den nativen IPsec-Stack des Kernels 2.6. Eine Aufnahme dieser Funktionalität in den Standardkernel war und ist daher eher unwahrscheinlich. Das Filtern von IPsec-Verkehr auf Kernel 2.6 stellt damit den Firewall-Administrator vor neue Aufgaben.
Markierung
Bei der IPsec-Implementierung des Kernels 2.6 durchlaufen alle Pakete die Forward-Kette [7], sowohl die aus einem Tunnel stammenden als auch jene, die im Klartext übers Internet eintreffen. Es gibt zunächst keine Möglichkeit, zwischen diesen beiden Paketsorten zu unterscheiden. Die Entschlüsselung und Authentizitätsprüfung erfolgten bereits. Damit ist es nicht unmittelbar möglich, Telnet-Pakete nur zu erlauben, wenn sie durch das VPN eintreffen.
Erste Lösungen für dieses Problem nutzten Markierungen der Pakete mit IPtables. Eine Regel markiert die verschlüsselten IPsec-ESP-Pakete in der Input-Kette, eine weitere Regel in der Forward-Kette wertet die Markierung nach dem Entschlüsseln aus (Listing 2a). Die Marke überlebt die IPsec-Aktionen.
|
Listing 2a: Markierung beim |
|---|
01 iptables -t mangle -A INPUT -p esp -j MARK --set-mark 50 02 iptables -A FORWARD -m mark --mark 50 -j ACCEPT |
Das Gleiche passiert beim Senden (Listing 2b): Die zu verschlüsselnden Pakete in der Forward-Kette markieren und in der Mangle-Postrouting-Kette prüfen, ob IPsec alle markierten Pakete wirklich verschlüsselt hat. Diese Variante funktioniert zwar, doch ist die Anwendung besonders bei mehreren Tunnels sehr umständlich. Einfacher klappt es mit dem neuen Policy-Match.
|
Listing 2b: Markierung beim |
|---|
01 iptables -t mangle -A FORWARD -p tcp --dport 23 -j MARK --set-mark 50 02 iptables -t mangle -A POSTROUTING -p ! esp -m mark --mark 50 -j DROP |
Policy-Match
Seit Version 1.3.5 enthält das »iptables«-Kommando das Policy-Match. Mit ihm erkennt die Firewall in der Forward-Kette, ob ein Paket durch eine IPsec-Policy geschützt ist (Abbildung 2). Eine Regel kann sogar definieren, durch welchen Tunnel die Pakete fließen müssen. Listing 3 akzeptiert nur Telnet-Pakete, die durch einen IPsec-Tunnel kommen, der per ESP verschlüsselt ist.
|
Listing 3: |
|---|
01 iptables -A FORWARD -p tcp --dport 23 -m policy --dir out --pol ipsec --proto esp --mode tunnel -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 02 iptables -A FORWARD -m policy --dir in --pol ipsec --proto esp --mode tunnel -m state --state ESTABLISHED,RELATED -j ACCEPT |
Die Option »–dir« unterscheidet, ob die Policy das Paket verschlüsselt (»out«) oder entschlüsselt hat (»in«). Die Option »–pol« trennt geschützte (»ipsec«) und nicht durch IPsec behandelte Pakete (»none«). Mit »–proto« wählt der Admin, ob ESP das Paket verschlüsseln und authentifizieren soll (»esp«), ob das AH-Protokoll lediglich die Integrität und Authentizität sichert (»ah«, siehe Kasten “IPsec-Funktionsweise”) oder ob das Paket nur komprimiert ist (»ipcomp«). Mit »–mode« unterscheidet IPtables, ob das Paket im Tunnelmodus oder im Transportmodus durchs Netz läuft.
|
IPsec-Funktionsweise |
|---|
|
Die IPsec-Protokolle wurden ursprünglich für das neue Internetprotokoll IPv6 entwickelt. Sie sorgen für Authentizität, Integrität und Vertraulichkeit der übertragenen Informationen. Hierzu signieren und verschlüsseln sie die übertragenen Pakete. Es stehen zwei Protokolle zur Verfügung: AH und ESP. Während AH (Authentication Header) nur die Signatur beherrscht, kann ESP (Encapsulation Security Protocol) signieren und verschlüsseln. Daher verwenden VPNs meist ESP. Beide Protokolle benötigen zum Signieren und Verschlüsseln symmetrische Keys und Angaben über den zu verwendenden Algorithmus. Diese kann der Administrator fest auswählen (Manual-keyed Connections). Besser sind jedoch Automatic-keyed Connections, bei denen die Rechner die Informationen per IKE-Protokoll aushandeln (Internet Key Exchange). Während ESP und AH als Transportprotokolle bei Linux im Kernel implementiert sind, spricht ein Userspace-Daemon das IKE-Protokoll. Das ist entweder Pluto (Openswan [4], Strongswan [5]) oder Racoon (Netkey-IPsec in Kernel 2.6 [1]). Die ausgehandelten Informationen landen anschließend in zwei Datenbanken:
Während die Security Policies definieren, welche Pakete IPsec mit welchen Protokollen zu schützen hat, enthalten die Security Associations alle Angaben über die zu verwendenden Schlüssel und Algorithmen. Existiert keine Security Policy, schützt IPsec auch kein Paket. Für komplexe Anforderungen kann der Admin Security Policies auch verschachteln, um zum Beispiel ein Paket zunächst mit IPcomp zu komprimieren, anschließend mit ESP zu verschlüsseln und zusätzlich mit AH zu authentifizieren. Die SAD und die SPD lassen sich bei Openswan mit den Befehlen »setkey -D« beziehungsweise »setkey -DP« anzeigen. |
Richtungweisend
Zwingend ist beim Policy-Match die Richtungsangabe mit »–dir«. Weitere Parameter spezifizieren die Tunnelendpunkte (»–tunnel-src« und »–tunnel-dst«), »–spi« gibt die SPI des Tunnels an. Letzteres ist aber kaum sinnvoll, da der IKE-Daemon die Security Parameter Indices dynamisch aushandelt.
Weit nützlicher ist der Einsatz der Option »–reqid«. Jede Policy kann eine eigene Request-ID erhalten, die auch einige IKE-Daemons setzen. Zum Beispiel nutzt Pluto (von Openswan und Strongswan) diese Funktion. Damit gelingt es auch bei dynamischen IP-Adressen, die Tunnel spezifisch in der IPtables-Regel auszuwählen.
Bei geschachtelten Policies prüft Netfilter wahlweise auch deren Reihenfolge und Vollständigkeit. Hierzu dient die Option »–strict« in der IPtables-Regel; auf sie folgt die Definition der einzelnen Policies, die mit »–next« getrennt sind. Die Regel in Listing 4 prüft folglich, ob der Kernel ein Paket zunächst komprimiert und anschließend verschlüsselt überträgt. Ohne die Option »–strict« würde bereits die Angabe eines Elements der Policy genügen, um auf die komplette geschachtelte Policy zuzutreffen. Bei »–strict« muss die Regel dagegen alle Teil-Policies definieren.
|
Listing 4: Verschachtelte |
|---|
01 iptables -A FORWARD -m policy --dir out --strict --proto ipcomp --next --proto esp -j ACCEPT |
Alles in allem erlaubt das Policy-Match genaueres und besseres Filtern als die alten virtuellen Netzwerkkarten. Hier konnte IPtables nur prüfen, ob Freeswan die Pakete irgendwie verarbeitet hat. Ob ESP die Übertragung schützt und zu welchem Tunnelendpunkt das verschlüsselte Paket fließt, konnte die Firewall nicht prüfen und musste sich auf Freeswan verlassen.
SNAT
Das virtuelle Interface hatte noch einen weiteren wichtigen Vorteil: Die Firewall konnte die unverschlüsselten Pakete, bevor sie sie durch den Tunnel schickte, mit Source-NAT behandeln. Hierzu genügte folgende Regel:
iptables -t nat -A POSTROUTING -o ipsec0 -j MASQUERADE
SNAT ist etwa nötig, wenn der Tunnel nur die IP-Adresse des VPN-Clients zulässt, aber weitere Rechner hinter dem Client das VPN nutzen sollen. Ein weiteres Einsatzszenario ist ein VPN, das zwei Netzwerke mit identischen privaten Adressen verbindet. Dann ist sogar ein NAT in beiden Richtungen nötig (Twice-NAT). Mit dem Kernel 2.6 klappte dies zunächst nicht, da die Pakete beim Erreichen der NAT-Postrouting-Kette bereits verschlüsselt sind (Abbildung 3).

Abbildung 3: Da der Linux-Kernel 2.6 die IPsec-Pakete bereits vor der Postrouting-Kette verschlüsselt, scheitert das oft nötige Source-NAT. Erst neue Kernelpatches umgehen diese Hürde.
Patrick McHardy hat aber einige Patches geschrieben [2], die unter anderem dafür sorgen, dass Pakete die Postrouting-Kette zweimal durchlaufen. Zunächst wandert das Klartextpaket durch alle Ketten. Anschließend durchläuft es verschlüsselt die IPtables-Ketten, als sei es ein lokal erzeugtes Paket. Es beginnt mit den Output-Chains und betritt dann Postrouting.
So kann NAT sowohl das Klartextpaket vor seiner Verschlüsselung als auch das verschlüsselte Paket in den Postrouting-Ketten behandeln. SNAT ist nun möglich. Diese Patches waren bis vor kurzem noch nicht funktionstüchtig, aber seit Linux-Kernel 2.6.16 sind sie fester und funktionierender Bestandteil. Ein Patch ist nicht mehr erforderlich. Einige Distributionen (etwa Fedora Core 5) haben diese Patches auch schon in den Distributions-Kernel 2.6.15 eingebaut. Folgende einfache Regel maskiert Pakete, die durch einen IPsec-Tunnel wandern:
iptables -t nat -A POSTROUTING -p tcp -m policy --dir out -j MASQUERADE
Durch diese neue Entwicklung gibt es nun keinen objektiven Grund mehr, das Upgrade eines VPN-Gateway von Kernel 2.4 auf Kernel 2.6 zu fürchten. Natürlich ist eine Anpassung der Firewallregeln erforderlich. Der Lohn für diese Mühe sind viele weitere Vorteile des Kernels 2.6 auf der Firewall. Sicherheitslösungen wie App Armor oder SE Linux stehen nur für den Kernel 2.6 zur Verfügung.
Zukunftsträchtig
Auf lange Sicht werden sicherlich auch Anbieter von Linux-VPN- und Firewall-Lösungen den Wechsel auf Kernel 2.6 vollziehen. Bisher war das Fehlen der virtuellen »ipsecX«-Netzwerkkarten häufig ein K.-o.-Kriterium. Das Policy-Match ersetzt zusammen mit den McHardy-Modifikationen die alte Architektur aber vollständig und erweitert sogar die Einflussmöglichkeiten der Firewall. (fjl)
|
Infos |
|---|
|
[1] Ralf Spenneberg, “Sicherer Transport – Virtuelle Private Netze mit Linux 2.6 und IPsec”: Linux-Magazin 05/03, S. 60 [2] Netfilter: [http://www.netfilter.org] [3] Freeswan: [http://www.freeswan.org] [4] Openswan: [http://www.openswan.org] [5] Strongswan: [http://www.strongswan.org] [6] Ralf Spenneberg, “Linux Firewalls mit IPtables”: Addison Wesley 2006 [7] Michael Becker und Sebastian Claßen, “Firewalling bei IPsec-Einsatz unter Kernel 2.6”: Linux-Magazin 12/04, S. 34 |








