HOWTO OpenVPN unter Apple MacOS-X

Das OpenVPN-HOWTO (http://openvpn.net/howto.html) geht nur auf die Verwendung von OpenVPN unter Linux und Windows ein. MacOS-X wird dort nicht berücksichtigt. Zwar gab es in der c’t einen Artikel zu OpenVPN unter MacOS-X, allerdings wurde in diesem Artikel nicht auf die Konfiguration des Servers eingegangen. Darum an dieser Stelle ein HOWTO für OpenVPN unter MacOS-X. Um dieses HOWTO nachzuspielen, sind keine Programmierkenntnisse erforderlich. Allerdings sollte man wissen, was eine Shell ist und auch den Texteditor „vi“ rudimentär bedienen können (oder man verwendet einen anderen Texteditor wie Smultron oder TextMate).

Man verwendet ein VPN (Virtuelles Privates Netzwerk) um über öffentliche/unsichere Netzwerke eine Verbindung mit einem privaten/sicheren Netzwerk aufzubauen. Bei dem privaten Netzwerk kann es sich um das Mini-Home-Netzwerk hinter dem eigenen DSL-Router handeln.

Bei einem VPN wir ein Tunnel zwischen dem Client und dem VPN-Server aufgebaut. Durch den Tunnel fließen dann alle Datenpakete verschlüsselt. OpenVPN ist eine Software zur Realisierung eines solchen VPNs. OpenVPN baut eine verschlüsselte Verbindung zwischen zwei Rechnern (oder zwei Gateways oder Rechner und Gateway) über das offene, unverschlüsselte Internet auf.

OpenVPN kommt – im Ggs. zu IPSec usw. – mit nur einem Protokoll und einem Port aus, ist also recht schlank und einfach. So kann man auch NAT-Router einfach so einrichten, dass sie OpenVPN nicht blocken. Mehr zu OpenVPN findet man in der Wikipedia unter (http://de.wikipedia.org/wiki/OpenVPN).

OpenVPN bentutzt OpenSSL zur Verschlüsselung. Als Protokolle lassen sich TCP oder UDP einsetzen.

Ein Client kann sich gegenüber dem Server mit verschiedenen Verfahren authentifizieren. Für kleine Netze kommen zwar Preshared-Keys in Betracht, sicherer sind allerdings Zertifikate. Ein Client braucht ein gültiges (signiertes) Zertifikat, im sich gegenüber dem Server auszuweisen.

Der Aufbau einer OpenVPN-Verbindung läuft wie folgt ab: Ein Client baut eine Verbindung zum Server auf. Ein X.509-Zertifikat des Servers wird geprüft, um festzustellen, ob der Server wirklich der gewünschte OpenVPN-Server oder ein Man-in-the-Middle ist. Die Prüfung wird mit dem öffentlichen Schlüssel der CA (Certificate Authority) durchgeführt. Es gibt kommerzielle CAs, in diesem HOWTO wird allerdings selbst CA gespielt (demoCA).
Wenn das Zertifikat gültig ist, dann wird eine verschlüsselte Verbindung aufgebaut.

Diese Verbindung erfolgt über SSL aka. TLS. Dabei nutzt OpenVPN die offene SSL-Implementierung OpenSSL. Eine private IP-Adresse bekommt der Client vom Server über den Tunnel. Die Endpunkte des Tunnels sind virtuelle Interfaces (TUN/TAP). MacOS-X bringt diese nicht mit. Darum müssen diese nachinstalliert werden.

Unter Ubuntu-Linux (mit apt) oder Windows (mit einem Installer) lässt sich OpenVPN recht leicht mit Binär-Paketen installieren. Für MacOS gibt es solche Binärpakete leider (noch?) nicht. Darum muss man OpenVPN unter MacOS selbst bauen. Dazu sind die XCode-Tools von Apple (auf der Installations-CD #1 von MacOS-X) nötig.

Zunächst muss man zwei Pakete herunterladen:

* LZO: http://www.oberhumer.com/opensource/lzo/
* OpenVPN: http://openvpn.net

Beide Downloads kann man – sofern StuffIt o.ä. installiert ist – per Doppelklick auf dem Desktop entpacken und in das Home-Verzeichnis verschieben. Spätestens danach muss man die Shell öffnen und damit weiterarbeiten.

LZO ist eine Kompressionsbiliothek, die die Datenpakete von OpenVPN komprimiert. So reagiert das virtuelle Netzwerk über eine langsame Internet-Verbindung weniger träge, da die verschlüsselten Datenpakte komprimiert werden.

LZO baut man im Unix-üblichen configure–make–make-install-Dreischritt (btw: die Tilde (Schlangenlinie) „~“ befindet sich bei MacOS unter Alt+n(+Leertaste)):


cd ~/lzo-2.02/
./configure

Sollte nun die Meldung „configure: error: no acceptable C compiler found in $PATH“ erscheinen, scheinen die XCode-Tools nicht installiert zu sein. Ansonsten sollten rechte viele Checks über das Terminal laufen, bis die Meldung „Type `make‘ to build LZO. Type `make install‘ to install LZO. After installing LZO, please read the accompanied documentation.“ erscheint. Dieser Aufforderung folgen wir.


make
sudo make install

Nach dem dies erfolgreich durchgelaufen ist („Libraries have been installed in: /usr/local/lib“) wird OpenVPN installiert. OpenVPN ist die eigentliche VPN-Software.

Man wechselt in das Verzeichnis, in das OpenVPN entpackt wurde, baut und installiert es:


cd ~/openvpn-2.0.9/
./configure
make
make check
sudo make install

Nun sollte OpenVPN in usr/local/sbin/openvpn installiert worden sein. Aus bequemlichkeitsgründen trägt man OpenVPN in die PATH-Umgebungsvariable ein, die in der versteckten Datei .bash-profile gesetzt werden kann. Man editiert diese Datei mit VI:


cd ~
vi .bash_profile

In diese Datei trägt man nun den zusätzlichen Pfad ein. Evtl. sind dort bereits Pfade (wie im Beispiel Python) eingetragen, die man dann nur erweitern muss:


PATH="/Library/Frameworks/Python.framework/Versions/Current/bin:/usr/local/sbin:${PATH}"
export PATH

Damit die Änderung am Bash-Profile gültig wird, muss man die das Terminal neu starten. Ob die Änderungen wirksam sind, kann man über den Befehl

env

kontrollieren. Die PATH-Umgebungsvariable sollte und den Pfad „/usr/local/sbin“ enthalten.

Nun lässt sich OpenVPN testweise starten:


openvpn --version

Eine Meldung wie die folgende sollte erscheinen:

OpenVPN 2.0.9 powerpc-apple-darwin8.10.0 [SSL] [LZO] built on Oct 15 2007
Developed by James Yonan
Copyright (C) 2002-2005 OpenVPN Solutions LLC

Wie man an dem Text „[LZO]“ erkennt, wurde von OpenVPN die Kompressionsbibliothek LZO erkannt und eingebunden 🙂

Nun muss man einen Schlüssel für die Certificate Authority erzeugen:


cd /System/Library/OpenSSL/
sudo openSSL genrsa -des3 -out ca.key 2048

Auf die Frage „Enter pass phrase for ca.key:“ sollte man mit einem möglichst komplizierten Passwort antworten, denn eine Verschlüsselung ist stets so stark (oder schwach) wie das gewählte Passwort. Eine best-practice ist, die Anfangsbuchstaben eines langen Satzes kombiniert man Zahlen und Sonderzeichen zu verwenden. Den erzeugen Schlüssel sollte man auf einem USB-Stick, auf dem auch der GPG/PGP-Key gesichert ist, sichern, damit er nicht verloren geht. Das Passwort sollte man nicht vergessen (oder im Schlüsselbund sichern).


mkdir /Volumes/USB DISK/OpenVPN
cp ca.key /Volumes/USB DISK/OpenVPN/

Nachdem man nun den Schlüssel hat, kann man die Certificate Authority selbst erzeugen:


sudo openSSL req -new -x509 -days 9999 -key ca.key -out ca.crt

Im folgenden Dialog beantwortet man die Fragen am „sinnvollsten“ wie folgt:


Country Name (2 letter code) [AU]:KZ
State or Province Name (full name) [Some-State]:Kasachstan
Locality Name (eg, city) []:Astana
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Menin Kasachstanym Ltd.
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:borat
Email Address []:borat@whitehouse.gov

Die Aktionen, die man für die Certificate Authority durchführen musste, müssen nun auch für das Server-Zertifikat durchgeführt werden. Eigentlich ist für OpenVPN gar kein „richtiges“ Server-Zertifikat nötig. Normalerweise wird ein Server-Zertifikat für viel Geld von Verisign u.a. gekauft. Normalsterbliche gebe das Geld lieber anders aus. Darum erzeugen wir uns das Server-Zertifikat selbst.


sudo openSSL genrsa -out server.key 2048

Auch diesen Server-Key sichern wir auf dem USB-Stick.


cp server.key /Volumes/USB DISK/OpenVPN/

Nun legen wir eine Certifikate Signing Request an (nicht um diesen an Verisign zu stellen):


sudo openSSL req -new -key server.key -out server.csr

Die nun folgende Dialoge beantwortet man wie beim Erstellen der Certificate Authority. Den CSR sichert man wieder auf dem USB-Stick.


cp server.csr /Volumes/USB DISK/OpenVPN/

Um den CSR selbst zu signieren, legen wir eine geeignete Ordnerstruktur mit einigen Dateien an:


sudo mkdir -p demoCA/private
sudo cp ca.key demoCA/private/cakey.pem
sudo cp ca.crt demoCA/cacert.pem
sudo mkdir demoCA/newcerts
sudo touch demoCA/index.txt
sudo /bin/sh -c "echo "01" > demoCA/serial

Mit dieser Ordnerstruktur können wir den CSR selbst signieren.


sudo openSSL ca -policy policy_anything -in server.csr -out cerver.crt

Auf die Frage „Sign the certificate? [y/n]“ antwortet man mit „y“. Dito auf „1 out of 1 certificate requests certified, commit?“ mit „y“. Nun sollte das Zertifikat erzeugt sein. Dies lässt sich prüfen.


cd demoCA
openssl x509 -noout -in cacert.pem -issuer -subject -dates

Dieses Zertifikat sichert man auf den USB-Stick und sichert es gegen unbefugten Zugriff:


cd demoCA
cp cacert.pem /Volumes/USB DISK/OpenVPN
sudo chmod 700 newcerts/
sudo chmod 700 private/
sudo chmod 700 cacert.pem

Letztlich werden nur noch Parameter für die Verschlüsselung angelegt. Die Verschlüsselung wird über den Diffie-Hellman-Schlüsselaustausch (http://de.wikipedia.org/wiki/Diffie-Hellman-Schlüsselaustausch) realisiert. Darum muss die Datei dh2048.pem erzeugt werden:


cd ..
sudo openssl dhparam -out dh2048.pem 2048

Da dieses Tool meldet „This is going to take a long time“, ist nun Zeit für eine Pause… puh!

Nun kann man für einzelne Client-Zertifikate erzeugen. Folgend für ein iBook:


sudo mkdir certs
sudo openssl req -new -newkey rsa:2048 -out certs/iBook-crs.pem -keyout private/iBook-key.pem -nodes

Diese Client-Zertifikate muss man natürlich aus signieren:


sudo openssl x509 -req -in certs/iBook-crs.pem -out certs/iBook-cert.pem -CA demoCA/cacert.pem -CAkey demoCA/private/cakey.pem -CAserial demoCA/serial -days 9999

Die Server-Zertifikate kopiert man nun in eine Verzeichnis, in dem ein Nutzer, der OpenVPN startet, lesen kann:


sudo mkdir /etc/openVPN
sudo cp server.crt /etc/openVPN
sudo cp server.key /etc/openVPN
sudo cp dh2048.pem /etc/openVPN
sudo cp ca.crt /etc/openVPN

Für den Mac-Client saugt man sich gleich schon Sandro Laubs „Tunnelblick“ (http://www.tunnelblick.net/) und kopiert es auf den USB-Stick. Die Client-Zertifikate kopiert man ebenfalls auf den USB-Stick, um sie auf einen Client (z.B. das oben schon angesprochene iBook) zu übertragen:


cp ~/Desktop/Tunnelblick-versal-3.0b6.dmg /Volumes/USB DISK/
sudo cp certs/iBook-cert.pem /Volumes/USB DISK/
sudo cp private/iBook-key.pem /Volumes/USB DISK/

Um OpenVPN nutzen zu können, benötigt man ein IP-Tunnel-Kernel-Extension. Einen Installer dafür findet man bei Mattias Nissler (http://www-user.rhrk.uni-kl.de/~nissler/tuntap/). Diesen installiert man mit dem Installer. Ein Client, der Tunnelblick verwendet, braucht diesen Treiber nicht, da Tunnelblick alles mitbringt.

Der OpenVPN-Server benötigt eine Konfigurationsdatei „server.conf“. Diese Datei legt man unter „/etc/openVPN/server.conf“ ab. Eine Beispiel-Konfigurationsdatei kann man direkt bei OpenVPN herunterladen (http://openvpn.net/howto.html#examples). Als Besonderheit wird OpenVPN auf dem HTTPS-Port 443 gestartet. Damit kommt man auch durch eine restriktive Firewall auf den Server. Des weiteren müssen unsere Keys und CAs in diese Konfigurationsdatei eingetragen werden. Da MacOS-X ein Unix-Betriebssystem ist, existiert dort der User und die Gruppe „nobody“, unter dessen Account OpenVPN laufen soll. Dazu müssen die entsprechenden Stellen in der Konfigurationsdatei gefunden und geändert werden:


cipher AES-256-CBC

dev tun

proto udp

port 443

ca /etc/openVPN/ca.crt
cert /etc/openVPN/server.crt
key /etc/openVPN/server.key # This file should be kept secret

dh /etc/openVPN/dh2048.pem

push "route 100.8.0.1 255.255.255.0"

user nobody
group nobody

Die Werte


cipher AES-256-CBC

dev tun

proto udp

port 443

sollte man sich notieren, da man diese auf dem Client genauso konfigurieren muss. Evtl. kann man gleich die Server-Konfiguration als Referenz auf dem USB-Stick ablegen.

Nun kann man testweise den OpenVPN-Server starten:


sudo openvpn /etc/openVPN/server.conf

Der Server sollte sich, wenn alles richtig konfiguriert ist, wie folgt melden:


"Initialization Sequence Completed"

Damit das Routing richtig funktioniert, muss man unter MacOS-X noch die Datei „/etc/hostconfig“ bearbeiten:


sudo vi /etc/hostconfig

Dort fügt man einen Eintrag hinzu und startet den Rechner neu:


IPFORWARDING=YES

Der Name des eigenen Servers sollte über das Internet auflösbar sein. Also sollte man auf dem Server DynDNS ö.ä. verwenden. DynDNS lässt sich in den meisten DSL-Routern einstellen. Bitte dafür einfach mal auf der Konfigurations-Oberfäche des eigenen Routers herumspielen, bis es funktioniert. Außerdem muss der HTTPS-Port 443 auf den eigenen Rechner geforwardet werden. Auch das muss in der Router-Konfiguratione eingerichtet werden. Der Menüpunkt dafür heißt meist Virtueller Server o.ä.. Schließlich muss der HTTPS-Port noch in der MacOS-X-Firewall freigeschaltet werden.

OpenVPN lässt sich z.B. mit Lingon als Autostart-Item einrichten. Alternativ lässt sich auch ein Startup-Item unter „/Library/StartupItems/openvpn“ anlegen und ein Start-Script dort erstellen:

openvpn:


#!/bin/sh

##
# OpenVPN-Server
##


. /etc/rc.common

StartService()
{
ConsoleMessage "Starting OpenVPN-Server"
/usr/local/sbin/openvpn --daemon --cd /etc/openVPN
--config /etc/openVPN/server.conf
--writepid /var/run/openvpn.pid
}

StopService()
{
pid=$(GetPID openvpn)
if [ $? = 0 ]; then
ConsoleMessage "Stopping OpenVPN-Server"
kill -TERM "${pid}"
fi
}


RestartService () { StopService; StartService; }

RunService "$1"

StartupParameters.plist:


<plist version="1.0">
<dict>
<key>Description</key>
<string>openvpn</string>
<key>Provides</key>
<array>
<string>openvpn</string>
</array>
<key>Requires</key>
<array>
<string>Network Configuration</string>
<string>tun</string>
</array>
<key>Uses</key>
<array>
<string>IPServices</string>
</array>
</dict>
</plist>

Damit ist der OpenVPN-Server eingerichtet. Im zweiten Teil dieses HOWTOs (http://simonox.blogspot.com/2007/11/howto-openvpn-unter-apple-macos-x-als.html)wird der Client mit dem Server verbunden.

15 Gedanken zu „HOWTO OpenVPN unter Apple MacOS-X“

  1. Hi, danke für die Anleitung. Leider bekomme ich auf meiner Windows Mühle folgende Warnings:

    Route addition via IPAPI failed
    route ADD 192.168.178.0 MASK 255.255.255.0 10.8.0.5
    Warning: route gateway is not reachable on any active network adapters: 10.8.0.5

    Ich hoffe jemand kann hier weiterhelfen. Viele Grüße

  2. hallo
    ich habe tunnelblick installiert und kann damit verbinden. nur… wie kann ich mich nun mit dem entfernten server verbinden? habe über den finder: mit server verbinden … doch akzeptiert es die adresse nicht. an-pingen kannich sie.
    kann mir jemand helfen?

    vielen dank
    grüsse
    b

  3. Super Anleitung!! Danke Und jetzt kaufe ich mir ein Buch und versuche zu verstehen was ich da eigentlich gemacht habe. Aber es funktioniert erstmal 🙂

    Gruß Lutz

    @ Anonymous
    Deinen Server erreichst Du im Finder mit (apfel+k)
    und dann afp://10.8.0.1 eintragen

  4. >wie kann ich mich nun mit dem entfernten server verbinden?

    ganz normal. wenn man z.B. ein smb-share über das vpn verweden möchte, verbindet man sich z.B. ueber die IP-Adresse über den Finder (apfel-k) damit.

  5. ./openvpn: line 30: $1: unbound variable

    Das StartUp Skript startet nicht mit der obigen Fehlermeldung. Irgend eine Idee?

    Vielen Dank für die ausführliche Anleitung!

  6. Hi SimonOX,

    danke für die Anleitung. Leider funktioniert bei mir der Aufruf "sudo /bin/sh -c "echo "01" > demoCA/serial" nicht. OSX bringt mich an ein "Groesser als Zeichen", also ein einfaches ">". Ich kann da nur ueber ctrl + c raus. Wenn ich z.B. die Eingabe ändere in "sudo /bin/sh -c "echo 01" > demoCA/serial", wird mir gemeldet "Permission denied"

    Ich bin auf OSX und Unix/Linux allerdings auch sehr neu. Danke fuer Deine Hilfe,
    Chris

  7. @Christoph
    Bin ich auch drüber gestolpert. du musst dir (sprich dem user als der du angemeldet bist) selbst schreibrechte für den Ordner '/System/Library/OpenSSL/demoCA' zuweisen.
    Geht zB im Finder mit Kontextmenü -> Informationen und dann unten unter 'Sharing&Zugriffsrechte'.

  8. Hallo SimonX,

    vielen Dank zunächst für die großartige Anleitung!

    Leider fehlt mir scheinbar eine Datei ‚openssl.cnf‘:
    sudo openSSL ca -policy policy_anything -in server.csr -out cerver.crt
    Using configuration from /System/Library/OpenSSL/openssl.cnf
    error loading the config file ‚/System/Library/OpenSSL/openssl.cnf‘
    29674:error:02001002:system library:fopen:No such file or directory:bss_file.c:104:fopen(‚/System/Library/OpenSSL/openssl.cnf‘,’rb‘)
    29674:error:2006D080:BIO routines:BIO_new_file:no such file:bss_file.c:107:
    29674:error:0E064072:configuration file routines:CONF_load:no such file:conf_def.c:197:

    Hast du einen Rat?

    Vielen Dank schonmal
    Axel

  9. Hallo SimonOX,

    du hast eine Superanleitung geschrieben, doch irgendwie bricht bei mir beim erstellen der LZO der Prozess ab.

    Hier die nachfolgende Meldung:
    mini:lzo name$ make
    make all-recursive
    Making all in include
    Making all in lzo
    make[3]: Nothing to be done for `all'.
    make[3]: Nothing to be done for `all-am'.
    Making all in src
    make[2]: Nothing to be done for `all'.
    Making all in lzotest
    make[2]: Nothing to be done for `all'.
    Making all in examples
    make[2]: Nothing to be done for `all'.
    Making all in tests
    make[2]: Nothing to be done for `all'.
    Making all in minilzo
    make[2]: Nothing to be done for `all'.
    mini:lzo name$

    Kannst du mir sagen, was nicht geklappt?

    Herzlichen Dank und viele Grüße,
    Steffen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.