Aus Linux-Magazin 08/2005

Anleitung: Firewalls untertunneln mit OpenVPN

Firewalls sind oft so vermauert, dass gerade noch der alltäglichen Surf-Betrieb möglich ist. Ein IRC- oder Streaming-Server findet keinen Weg mehr – es sei denn, OpenVPN untergräbt die Firewall.

Firewalls sind meist so konfiguriert, dass alles verboten ist, was nicht unbedingt für die tägliche Arbeit nötig ist. Selbst kleine Dienste wie die eigene Webcam am Schreibtisch oder ein kleiner IRC-Server lassen sich durch die Restriktionen nicht mehr betreiben. Hier hilft nur OpenVPN [1] mit einem privaten Tunnel unter der Firewall hindurch, dessen Inhalt zudem verborgen bleibt.

Firewall untergraben

OpenVPN braucht keine Root-Privilegien, um einen Tunnel aufzubauen, wenn das Programm Zugriff auf die virtuellen TUN/TAP-Devices hat, läuft es auch im Userspace. Im einfachsten Fall genügt ein Aufruf mit einigen Parametern, um ein VPN einzurichten. Die einzige erforderliche Datei ist der gemeinsame Schlüssel, den der Client per »openvpn –genkey –secret secret.key« anlegt und den der Admin dann auf den Server kopiert. Der Artikel aus [2] beschreibt die interne Arbeitsweise von OpenVPN und das erforderliche Routing und die Firewall-Regeln für den Tunnel.

Zum Tunneln von TCP/IP ist ein verbindungsloses Protokoll wie UDP am besten geeignet: Es vermeidet, dass die Timeouts der OpenVPN- sowie der gekapselten TCP-Verbindung gleichzeitig ablaufen, was schlimmstenfalls zu einer ganzen Lawine an Retry-Paketen führt. Firewalls und Router in Unternehmen oder Internetcafés verbieten aber meist, dass Clients UDP-Pakete aus dem Internet empfangen. Die einzige Alternative ist daher, auf TCP auszuweichen. Damit kann jedoch nur noch der Client den Aufbau des VPN anstoßen,

Zwei gekürzte Skripte für den Server und den Client sind in den Listings 1 und 2 abgedruckt (online auf [3]). OpenVPN kommt ohne Konfigurationsdateien aus, wenn die Kommandozeilen-Parameter alle für den Tunnel benötigten Informationen enthalten. Optionen, die der jeweilige Benutzer von Fall zu Fall ändern muss, sind in den Listings 1 und 2 jeweils am Anfang aufgeführt.

Der Server kommt mit vergleichsweise wenigen Angaben aus, OpenVPN benötigt lediglich die IP-Adressen der VPN-Schnittstellen auf dem Server (»LOCALIP«) und dem Client (»REMOTEIP«), das Tunnel-Device sowie die Portnummer und die Datei mit dem Schlüssel. Die Variable »MAXRATE« begrenzt die Transferrate in Senderichtung.

Traffic Shaping

Selbst auf gut angebundenen Servern kann Traffic Shaping sinnvoll sein, wenn es darum geht, den Tunnel möglichst unauffällig im allgemeinen Datenverkehr des Firmennetzes zu verbergen. Sein wichtigster Einsatzzweck liegt aber bei Heimnetzwerken, die per DSL angebunden sind. Da der Upstream deutlich geringer ist als der Downstream eines DSL-Clients, lässt sich die Internetverbindung abseits des Tunnels kaum noch benutzen. Der Autor verwendet das in Listing 1 angegebene Limit von 16 KByte/s für seine DSL-Verbindung mit maximal 256 KBaud Upstream – so bleibt mindestens die Hälfte der Bandbreite für andere Dienste wie Apache oder den normalen Surf-Betrieb frei.

Der OpenVPN-Aufruf in den Zeilen 10 bis 15 bedient sich der eingangs definierten Variablen. Wichtig sind insbesondere die Parameter »–daemon«, »–proto tcp-server« und »–persist-tun«. Mit »–daemon« startet OpenVPN als Daemon, sodass das Serverskript weiterläuft. In Listing 1 ist dies nicht wesentlich, da die Schleife von Zeile 17 bis 21 lediglich verhindert, dass das Skript vor OpenVPN endet. Sollten jedoch die Firewall geöffnet, Masquerading eingeschaltet oder das Routing verändert werden müssen, geschieht dies am besten hinter Zeile 15. Die entsprechenden Befehle zum Aufräumen gehören ans Ende des Skripts.

Client- und Server-Protokolle

Der Parameter »–proto tcp-server« sorgt dafür, dass OpenVPN als Server-Dienst arbeitet und auf eingehende TCP-Verbindungen wartet. Entsprechend verwendet der Client-Dienst das Protokoll »tcp-client«, wie in Zeile 13 von Listing 2 zu sehen. Sollte der Tunnel zwischenzeitlich unterbrochen werden, würde das TUN-Interface ohne »–persist-tun« jedes Mal geschlossen und bei erneuter Verbindung wieder geöffnet, womit die Routing-Einträge für den Tunnel verloren gingen und alle Verbindungen zusammenbrächen.

Abbildung 1: Mit TCP, das praktisch alle Firewalls mindestens für normalen Surf-Betrieb erlauben, baut der Client eine verschlüsselte Verbindung zum Open-VPN-Server auf und tunnelt darüber alle weiteren Protokolle.

Abbildung 1: Mit TCP, das praktisch alle Firewalls mindestens für normalen Surf-Betrieb erlauben, baut der Client eine verschlüsselte Verbindung zum Open-VPN-Server auf und tunnelt darüber alle weiteren Protokolle.

Die Schleife von Zeile 17 bis 21 ist in Listing 1 gegenüber dem Skript von [3] stark vereinfacht, es fehlen diverse Prüfungen, ob OpenVPN tatsächlich noch läuft – falls nicht, endet die Schleife und das Skript arbeitet etwaige Aufräumbefehle unterhalb von Zeile 21 ab. So lässt sich »openvpn-server.sh« problemlos von Init über einen Eintrag in der Datei »/etc/inittab« aufrufen.

Das Client-Skript aus Listing 2 ist doppelt so lang wie das des Servers, da es nach dem Aufruf von OpenVPN in den Zeilen 12 bis 17 noch das Routing des Client-Rechners anpasst. Dies kann jedoch erst dann erfolgen, wenn OpenVPN das Netzwerk-Device initialisiert hat, was die Zeilen 20 und 21 mit dem Exit-Status von »ipconfig« überprüfen.

Individuelles Routing

Ist das Tunnel-Device bereit, legt Zeile 22 eine statische Route zum OpenVPN-Server an. So ist die VPN-Verbindung von der Default-Route unabhängig, weshalb Zeile 24 diese Route löscht und Zeile 26 sie über den OpenVPN-Server als Gateway neu anlegt. Ab jetzt laufen alle neuen Netzwerkverbindungen über das VPN zum Server (Abbildung 1). OpenVPN hat somit die Firmenfirewall untergraben, der Client-Rechner hat ungehinderten und vor allem unbeobachteten Zugriff aufs Internet. Der Ping-Aufruf in Zeile 27 öffnet den bislang angelegten, aber noch geschlossenen Tunnel.

Damit das Client-Skript nicht blockiert, erfolgt die Ausführung der Routing-Befehle in den Zeilen 19 bis 32 maximal zehnmal. Die Schleife von Zeile 34 bis 38 ist identisch mit der aus dem Server-Skript in Listing 1, die Zeilen 40 und 41 räumen die Routing-Tabelle auf, wenn OpenVPN endet.

Der hier gezeigte Ansatz erfordert für jeden VPN-Client einen eigenen Server-Dienst, was bei mehreren Clients oder etlichen Filialen eines Konzern sehr schnell unübersichtlich wird. Doch selbst dieses Szenario berücksichtigt OpenVPN seit der Version 2.0 durch Public Key Infrastructures, CAs und Multiple-Client-Unterstützung. Für den privaten IRC-Server oder die Webcam für die Freundin reicht die einfache Konfiguration per Kommandozeile jedoch bestimmt.

Listing 1:
»openvpn-server.sh«

01 #!/bin/bash
02 
03 DEVICE="tun0"
04 PORT="1194"
05 LOCALIP="192.168.8.1"
06 REMOTEIP="192.168.8.128"
07 KEYFILE="/etc/openvpn/shared.key"
08 MAXRATE="16000"
09 
10 /usr/sbin/openvpn --daemon --dev $DEVICE 
11   --proto tcp-server --port $PORT  
12   --ifconfig $LOCALIP $REMOTEIP 
13   --secret $KEYFILE --persist-tun --ping 30 
14   --ping-restart 180 --shaper $MAXRATE 
15   --writepid /var/run/openvpn-${DEVICE}.pid
16 
17 while true; do
18   if [ ! -e /var/run/openvpn-${DEVICE}.pid ]; then
19     break
20   fi
21 done

Listing 2:
»openvpn-client.sh«

01 #!/bin/bash
02 DEVICE="tun0"
03 REMOTE="athome.dyndns.org"
04 GATEWAY="192.168.1.254"
05 PORT="1194"
06 LOCALIP="192.168.8.128"
07 REMOTEIP="192.168.8.1"
08 REMOTENET="192.168.42.0/24"
09 KEYFILE="/etc/openvpn/shared.key"
10 MAXRATE="16000"
11 
12 /usr/sbin/openvpn --daemon --dev $DEVICE 
13   --remote $REMOTE --proto tcp-client 
14   --port $PORT --ifconfig $LOCALIP $REMOTEIP 
15   --secret $KEYFILE --persist-tun --ping 30 
16   --ping-restart 180 
17   --writepid /var/run/openvpn-${DEVICE}.pid
18 
19 for ((i=0; i<10; i=$[$i+1])); do
20   ifconfig $DEVICE >/dev/null 2>/dev/null
21   if [ "$?" -eq 0 ]; then
22     route add $REMOTE gw $GATEWAY
23     if [ "$?" -eq 0 ]; then
24       route del default gw $GATEWAY
25       route add -net $REMOTENET gw $REMOTEIP
26       route add default gw $REMOTEIP
27       ping -c 1 $REMOTEIP >/dev/null 2>/dev/null &
28       break
29     fi
30   fi
31   sleep 5
32 done
33 
34 while true; do
35   if [ ! -e /var/run/openvpn-${DEVICE}.pid ]; then
36     break
37   fi
38 done
39 
40 route del $REMOTE gw $GATEWAY
41 route add default gw $GATEWAY

Infos

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

[2] Achim Leitner, “Offener Tunnel – OpenVPN”: Linux-Magazin 10/03, S. 29

[3] OpenVPN-Skripte: [https://www.linux-magazin.de/Service/Listings/2005/08/openvpn/]

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