Aus Linux-Magazin 10/2003

Virtuelle private Netze ohne Kernel-Modifikation: OpenVPN

Der einfach zu konfigurierende OpenVPN-Daemon nutzt das Tun-Device und arbeitet selbst im Userspace. Das UDP-Protokoll verwendet TLS-Verfahren zur Authentifizierung und kann damit als sehr sicher gelten.

Um IP-Pakete zu tunneln, braucht eine VPN-Software Zugang zum Kernel. Während Freeswan dazu als eigenes Kernelmodul realisiert ist, setzt OpenVPN[1] auf ein vorhandenes Modul (Tun/Tap) und arbeitet komplett im Userspace. Damit ist es sehr einfach in Betrieb zu nehmen. Seit 1.5-beta3 ist OpenVPN selbst für Windows verfügbar, bereits seit längerem unterstützt es neben Linux noch Mac OS X, Solaris, FreeBSD, NetBSD und OpenBSD.

OpenVPN ist zwar nicht zu IPsec kompatibel, dennoch verwendet es ein Standardprotokoll: TLS (Transport Layer Security[4]). Der Nachfolger von Netscapes SSL (Secure Sockets Layer), kommt bei der Authentifizierung mit X.509-Zertifikaten zum Einsatz.

Abbildung 1 verdeutlicht das VPN-Prinzip: Laptop und Server sind über ein beliebiges Netz verbunden und verwenden dort ihre reale IP-Adresse. Das VPN gibt Laptop und Server je eine zusätzliche, virtuelle IP-Adresse. Alle Daten, die über die virtuellen Adressen gesendet werden, verpackt OpenVPN in UDP-Pakete und sendet sie an die reale IP des Gegenübers. Der Empfänger packt die Daten aus und behandelt sie so, als wären sie über seine virtuelle Adresse hereingekommen. Es entsteht ein Tunnel zwischen Laptop und Server.

Grabungsarbeiten

Das folgende Beispiel geht davon aus, dass beide Rechner über »eth0« an das reale Netz angeschlossen sind – bei WLAN, ISDN, Modem oder DSL ist das entsprechende Interface einzusetzen. Neben dem hier dargestellten Client-to-Site-VPN kann OpenVPN auch ganze Standorte vernetzen, dazu ist lediglich das Routing anzupassen. Im Bridge-Modus verbindet es zwei Teile eines LAN sogar transparent. Im Idealfall nutzen beiden Tunnelendpunkte statische IPs. Für dynamische Adressen empfiehlt sich DynDNS[5], um jederzeit die aktuelle IP-Adresse des Gegenübers per festem DNS-Namen zu erhalten.

Als Client dient im Folgenden ein Laptop, der sich mit dem VPN-Server verbindet. Für erste Tests ist es sinnvoll, beiden OpenVPN-Rechnern einen gemeinsamen geheimen Schlüssel zu geben, das Shared Secret:

openvpn --genkey --secret Geheimer.Key

Den Inhalt von » Geheimer.Key« dürfen nur die beiden Rechner kennen, er darf auch nur für Root lesbar sein – wer den Schlüssel kennt, kann den Tunnel problemlos knacken.

Um den Tunnel zu graben, benötigt OpenVPN die IP-Adresse oder den DNS-Namen des Zielrechners, den Namen des Tunneldevice (per Default »tun0«) sowie die beiden virtuellen IP-Adressen für das VPN sowie die Schlüsseldatei. Auf dem Client sieht das so aus:

openvpn --dev tun0 
  --remote Reale_Server-IP 
  --ifconfig Virtuelle_Laptop-IP 
    Virtuelle_Server-IP 
  --secret Geheimer.Key

Wer die Optionen lieber in eine Konfigurationsdatei schreibt, muss dafür nur die führende Striche »–« entfernen, jede Option in eine Zeile setzen und OpenVPN anschließend mit den Parameter »–config Datei« aufrufen.

Passender Ausgang

Auf dem Server sind die IP-Adressen anzupassen:

openvpn --dev tun0 
  --remote Reale_Laptop-IP 
  --ifconfig Virtuelle_Server-IP 
    Virtuelle_Laptop-IP 
  --secret Geheimer.Key

Die virtuellen Tunneladressen sind fast beliebig, sie müssen aber private Adressen sein und aus einem anderen Block stammen als die realen Adressen, um das Routing einfach zu halten. Reales und virtuelles Netz sind dann leicht zu unterscheiden.

Ob der Tunnel steht, zeigt ein abschließender Ping-Test: Auf dem Laptop ermittelt »ping Virtuelle_Server-IP«, ob der Server durch den Tunnel erreichbar ist. Wenn alles klappt, kann OpenVPN auch als Daemon laufen, der »–daemon«-Parameter sorgt für diesen Wandel. Aber Vorsicht: Jetzt muss die Datei, die den geheimen Schlüssel enthält, mit ihrem absoluten Pfad angeben sein.

Der richtige Weg

Laptop und Server müssen wissen, welche Pakete sie durch den Tunnel senden sollen. Das Routing zur virtuelle IP des Gegenübers klappt bereits, der OpenVPN-Aufruf setzt die Route für genau diese Adresse passend. Alle anderen Adressen leitet der Kernel wie bisher am Tunnel vorbei. Für den Weg vom Server zum Laptop genügt diese Wegewahl auch, solange der Laptop mit seiner neuen virtuellen Adresse angesprochen wird. Die alte reale Adressen dient nur noch als Endpunkt des Tunnels.

Der Weg vom Laptop zum Server und weiter zum restlichen Netz, das hinter dem Server liegt, erfordert dagegen etwas Handarbeit. Für den Fall, dass der Client nur das private Netz durch den Tunnel ansprechen, sämtliche anderen Internetzugriffe aber über seine eigene Anbindung führen soll, genügt bereits ein einzelnes Routing-Kommando auf dem Laptop:

route add -net Virtuelles_Netz netmask
  Netzmaske gw Virtuelle_Server-IP

Oft ist es aber besser, die komplette Internetanbindung des Clients durch den Tunnel zu leiten. So profitiert auch er vom Schutz der Firmenfirewall, die den Server vor Angriffen von außen abschottet. Andernfalls wäre der per VPN eingebundene Laptop ein Sicherheitsrisiko, der als Hintertür Angreifern den Weg ins interne Netz ebnet.

Mit einer neuen Defaultroute sendet der Laptop alle Pakete durch den Tunnel:

route del default
route add default gw Virtuelle_Server-IP

Nicht vom Defaultpfad betroffen sind die Pakete, die zur realen IP-Adresse des Servers gehen, dafür hat OpenVPN mit einem gezielten Routing gesorgt. Das sollte auch so bleiben, da der Tunnel selbst an dieser Adresse angedockt ist. Nun muss der Server noch wissen, dass er die ausgepackten Pakete bei Bedarf weiterzuleiten hat:

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

Listing 1: Firewall-Gerüst

01 # Nur OpenVPN-Pakete über reale IP annehmen:
02 iptables -A INPUT -i eth0 -p udp --dport 5000 -j ACCEPT
03 iptables -A INPUT -i eth0 -j DROP
04 # Nur OpenVPN-Pakete über reale IP senden:
05 iptables -A OUTPUT -o eth0 -p udp --dport 5000 -j ACCEPT
06 iptables -A OUTPUT -o eth0 -j DROP
07 iptables -A FORWARD -i eth0 -j DROP
08 # Kommunikation über Tunnel erlauben:
09 iptables -A INPUT -i tun0 -j ACCEPT
10 iptables -A OUTPUT -o tun0 -j ACCEPT

Feuerdämmend

Laptop und Server sind noch unter ihren realen Adressen erreichbar und damit auch eventuellen Angriffen ausgesetzt. Gegen diese Gefahr schützt eine Firewall. OpenVPN versendet die verschlüsselten Pakete über UDP an Port 5000 der Gegenseite. Über seine Netzwerkkarte darf der Laptop nur Pakete annehmen, die an seine reale IP-Adresse auf Port 5000 gerichtet sind (Listing 1, Zeilen 2 und 3). Die erste Inputregel könnte noch strenger sein und mit »-s Reale_Server-IP« festlegen, von welcher Adresse die Pakete stammen müssen. Auch das Senden und Weiterleiten von Paketen ist einzuschränken (Zeilen 5 bis 7).

Die Tunnelenden nehmen nur Pakete entgegen, die von einem authentifizierten Partner stammen – vorausgesetzt, dass OpenVPN nicht mit abgeschalteter Verschlüsselung arbeitet. Laptop und Server können allen Paketen vertrauen, die von einem »tun«-Device stammen, sie annehmen und verarbeiten. Auch das Senden in den Tunnel hinein muss erlaubt sein (Zeile 9 und 10). Der Server benötigt noch eine Forwarding-Regel und eventuell Masquerading, damit der Laptop auch nach außen senden kann:

iptables -A FORWARD -i tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 
  -j MASQUERADE
Abbildung 1: Der Laptop sendet IP-Pakete über das Interface »tun0«, der Kernel reicht sie über das Device »/dev/tun0« an OpenVPN weiter. Der Daemon verschlüsselt und signiert die Pakete, verpackt sie in UDP und schickt sie mit der realen IP-Adresse über »eth0« zur anderen Seite.

Abbildung 1: Der Laptop sendet IP-Pakete über das Interface »tun0«, der Kernel reicht sie über das Device »/dev/tun0« an OpenVPN weiter. Der Daemon verschlüsselt und signiert die Pakete, verpackt sie in UDP und schickt sie mit der realen IP-Adresse über »eth0« zur anderen Seite.

Installation

OpenVPN ist auf[1] als Sourcepaket erhältlich. Zum Übersetzen genügt der Dreisatz »./configure –disable-lzo && make && make install«, der Configure-Parameter »–disable-lzo« schaltet die LZO-Kompression ab. Wer Bandbreite sparen will, installiert besser die LZO-Bibliothek[3]. Auf jeden Fall erforderlich ist die OpenSSL-Bibliothek, zusammen mit den Entwicklerdateien.

Auf Debian-Systemen genügt das übliche »apt-get install openvpn«, die OpenVPN-Entwickler stellen aber auch RPM-Pakete für Red Hat Linux zur Verfügung.

Tun-Device

Das Tunneldevice ist in aktuellen Kerneln bereits enthalten, für ältere Versionen ist das Paket auf[2] erhältlich. Wer den Kernel selbst übersetzt, findet das Tun-Modul in der Sektion »Network device support« unter dem Namen »Universal TUN/TAP device driver support«. Er muss dann noch das passende Devicefile mit »mknod /dev/net/tun c 10 200« anlegen – bei manchen Distributionen lautet der Pfad auch »/dev/tun0« – und das Modul mit »modprobe tun« laden.

Weitere Features

Das einfache Shared-Secret-Verfahren stößt schnell an seine Grenzen, wenn viele Knoten im VPN eingebunden sind. Dann zeigt sich die TLS-Basis von ihrer besten Seite: Sie ist für den Einsatz von X.509-Zertifikaten ausgelegt. Wie man diese Zertifikate erstellt, hat bereits der Freeswan-Artikel erklärt.

OpenVPN unterscheidet im UDP-Modus nicht zwischen Client und Server, sondern arbeitet als Peer-to-Peer-Applikation. Wenn bei aktivierter »–float«-Option einer der Endpunkte eine neue IP erhält, etwa durch den verbreiteten Zwangsreset nach 24 Stunden, kann er mit seiner neuen realen Adresse den Tunnel unterbrechungsfrei weiterführen. TCP-Verbindungen bleiben bestehen – besonders praktisch beim FTP-Transfer sehr großer Dateien.

Wer häufiger große Files durch den Tunnel sendet, wird auch die Option »–shaper Bandbreite« schätzen. Sie begrenzt die Bandbreite in den Tunnel hinein auf die angegebenen Bytes pro Sekunde. Um beide Richtungen zu begrenzen, ist die Option an beiden Enden anzugeben. Für administrative Aufgaben besonders interessant: OpenVPN kann gleichzeitig mehrere Tunnel unterschiedlicher Bandbreite zwischen zwei Partnern öffnen. Das Routing entscheidet, welche Daten durch welchen Tunnel laufen.

Mit der Option »–ping Sekunden« sendet OpenVPN in regelmäßigen Abständen leere Pakete an seinen Partner (keine ICMP-Pings, wie der Name vermuten ließe). Auch im Leerlauf bemerken die Hosts somit einen Ausfall ihres Gegenübers. Wer dynamische IPs und DNS nutzt, bringt mit »–ping-restart Sekunden« den Daemon dazu, nach der abgelaufenen Zeit ohne Kontakt einen erneuten DNS-Lookup zu starten. So stellt er sich auf eine neue reale IP ein.

Durch die Firewall

Überquert der Tunnel eine Firewall, hält »–ping« deren Zustandstabellen (Connection Tracking) auf dem aktuellen Stand. Die Firewall weiß dann, dass die Verbindung noch in Betrieb ist.

Die Betaversion von OpenVPN 1.5 arbeiten ersatzweise auch mit TCP: Die Optionen lauten »–proto tcp-client« und »–proto tcp-server«. Dass TCP keine gute Basis für einen Tunnel ist, hat der Einführungsartikel dieser Themenstrecke (Seite 23) bereits erläutert. Wer aber hinter einer Firewall sitzt, die nur TCP akzeptiert, hat kaum eine andere Wahl, als auf dieses Verfahren zu setzen.

Infos

[1] OpenVPN: [http://openvpn.sf.net]

[2] TUN/TAP-Treiber: [http://vtun.sourceforge.net/tun/]

[3] LZO-Bibliothek: [http://www.oberhumer.com/opensource/lzo/]

[4] Achim Leitner, “Transport-Sicherung: Verschlüsselt und authentifiziert kommunizieren mit TLS”: Linux-Magazin 04/02, S. 50

[5] DynDNS: [http://www.dyndns.org/]

Device und Interface

In Linux erhalten Netzwerkinterfaces normalerweise kein Devicefile, es gibt kein »/dev /eth0«. Das erscheint zwar nicht ganz konsequent, ist aber auch nicht nötig – für die Kommunikation kommt die Socket-Schnittstelle zum Einsatz. Das Tun/Tap-Interface nutzt diesen Umstand und legt gegen die Regel doch ein Devicefile an. Damit kann ein Userspace-Daemon die IP-Pakete abgreifen, neu verpacken und weitersenden.

Der Daemon schreibt Pakete nach »/dev/tun0«, beim Kernel kommen sie über das »tun0«-Interface an. Jedes Paket, das der Kernel zu »tun0« leitet, erhält der Daemon über »/dev/tun0« (Abbildung 1). Das Interface funktioniert wie ein gewöhnliches Netzwerkinterface, man kann IP-Adressen daran binden, es ins Routing aufnehmen und Firewallregeln anwenden – nur sendet es die Daten nicht an eine Ethernet-Karte, sondern über ein Devicefile zu einem Prozess.

Das Tap-Interface gleicht Tun, es greift aber Ethernet-Frames statt der IP-Pakete ab. Mit diesem Device sind auch Bridge-VPNs möglich: Die Tunnelenden fungieren dann nicht als Router, sondern als Bridge.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben