Weltweit flexibles VPN dank OpenVPN und DigitalOcean

Neulich im Urlaub gab es -selbstverständlich- ein gutes WLAN im Hotel. ABER: Meine Lieblingsseite (bestehend hauptsächlich aus Cat Content) war in diesem Wlan gesperrt. Da ein Leben ohne Katzen aus dem Internet natürlich nicht lebenswert ist, musste eine Lösung her die sowohl auf meinem Laptop als auch auf meinem (iOS) Handy funktioniert…

Klar ist also: Es muss ein VPN her. Ein einfacher SSH-Tunnel mit SOCKS-Proxy funktioniert zwar auf dem Browser problemlos aber auf dem Handy will er nicht so recht. Außerdem möchten wir natürlich jeglichen weiteren Verkehr (DNS-Abfragen?) auch unsichtbar machen. Ein schönes VPN sorgt dafür dass unser kompletter Netzwerkverkehr (von Handy oder Computer) auf der einen Seite reinläuft und auf der anderen Seite wieder rauskommt. Das heißt niemand im unserem aktuellen Netzwerk/Wlan kann sehen was wir machen. (Jemand der aber im Rechenzentrum unseres OpenVPN Servers sieht könnte schon sehen was wir so surfen… das ganze ist also nicht annährend so anonym oder sicher wie z.B. Tor, welches mehrere verschlüsselte Verbindungen hintereinander schaltet)

Klar ist auch: Damit wir so unsichtbar wir möglich sind muss dieses VPN über Port 443 (SSL) und TCP gehen, damit ist es von normalem https-Traffic nicht unterscheidbar. Ein anderer Port könnte ja eventuell blockiert sein (und ja, viele andere Ports sind in einem FritzBox Gast-Wlan auch blockiert!).

Die Zusatzaufgabe ist: Das VPN sollte von verschiedenen Orten auf der Welt aus ins Internet gehen können. Denn man will ja vielleicht gerne mal als amerikanische, deutsche oder englische IP erscheinen um Seiten mit Geo-Sperren ansehen zu können (bestes Beispiel: Die Mediatheken der deutschen und amerikanischen Fernsehsender gehen nur für Bürger des entsprechenden Landes und Netflix hat auch andere Filme im Angebot je nachdem aus welchem Land man kommt…).

Als Informationsgrundlage habe ich zwei Quellen hergenommen, einmal das Buch “OpenVPN – Schritt für Schritt zum eigenen Server” von René Fürst und den Beitrag “How To Set Up an OpenVPN Server on Ubuntu 18.04” im Blog von DigitalOcean. Größtenteils sind die Befehle (leicht angepasst) aus dem Buch von René Fürst. An ein paar Stellen musste man etwas tricksen da es unter der neuen Ubuntu (18.04) und OpenSSL (1.1.0g-2ubuntu4.1) Version etwas anders läuft. Andernfalls wäre es ja einfach, und einfach ist langweilig!

DigitalOcean ist übrigens hier auch gleich ein gutes Stichwort, denn dort kommt unser Linux Server der unser OpenVPN macht hin. Warum? Ganz einfach: Es gibt weltweilt verteilt Rechenzentren, man kann die Domain gleich mit verwalten und man kann eine virtuelle Maschine in einen kostengünstigen Snapshot verpacken und so relativ wenig zahlen bis man die Maschine braucht. Wenn man sie braucht fährt man sie im gewünschten Teil der Welt aus dem Snapshot hoch, passt die Domain an und fertig. Bei mir kostet das ganze ca. 10 $-Cent im Monat. Die habe ich noch übrig…

Aber der Reihe nach. Erstmal bei DigitalOcean registrieren, ein bisschen Geld aufladen und eine virtuelle Maschine der kleinsten Größe starten. Das sind momentan 1 GB Ram mit 1 vCPU, 25 GB SSD und 1 TB Traffic pro Monat. Absolut ausreichend für uns und mit $5 pro Monat, bzw $0.007 pro Stunde auch für den kleinen Geldbeutel bezahlbar.

Nach dem hochfahren solltet ihr eine Mail mit der IP und dem root-Passwort bekommen haben. Wir melden uns per SSH an, installieren Updates und ein paar Programme und rebooten mal sicherheitshalber:

apt-get update
apt-get dist-upgrade
apt-get install screen vim htop pwgen
apt-get autoremove
apt-get clean
shutdown -r now

Jetzt richten wir den OpenVPN User ein. Mit diesem werden wir alles weitere durchführen, deshalb geben wir ihm sudo-Rechte:

adduser openvpn
usermod -a -G sudo openvpn

Ab jetzt also als User ‘openvpn’ weiter:
Nun aktivieren wir die Firewall (die brauchen wir später definitiv für unser OpenVPN und erlauben nur noch SSH-Traffic:

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Jetzt installieren wir openvpn und easy-rsa, hier weichen wir von der Anleitung von DigitalOcean ab, die es nicht empfiehlt dass der OpenVPN Server und der Server welcher die Keyfiles ausstellt (die CA) der gleiche Server ist. Nachdem es hier eigentlich nur drum geht dass wir Katzenvideos ansehen können ist das hier aber nicht relevant. Genausowenig wie die Tatsache dass wir unsere Schlüssel nicht mit einem Passwort versehen. Das ist alles möglich und hat auch alles seinen Sinn, aber für einen Server der vielleicht alle paar Monate mal für ein paar Tage läuft um OpenVPN zu machen halte ich das ganze für zuviel des Guten.

sudo apt-get install openvpn easy-rsa

Jetzt erstellen wir einen Ordner für die Zertifikate:

sudo make-cadir /home/openvpn/openvpn-ca
sudo chown -R openvpn:openvpn /home/openvpn/openvpn-ca
cd /home/openvpn/openvpn-ca

Und passen die Datei ‘/home/openvpn/openvpn-ca/vars’ entsprechend an (‘sudo vi /home/openvpn/openvpn-ca/vars’):

export KEY_COUNTRY="DE"
export KEY_PROVINCE="Bayern"
export KEY_CITY="Oettingen"
export KEY_ORG="Meine Firma"
export KEY_EMAIL="meine@mail.de"
export KEY_OU="Meine Abteilung"

export KEY_NAME="server"

Wie folgt finden wir herraus welche Version von OpenSSL wir haben:

dpkg -s openssl

Und tragen das auch mit ein in die Datei:

export KEY_CONFIG=$EASY_RSA/openssl-1.0.0.cnf

(es gibt keine aktuellere als die ‘openssl-1.0.0.cnf’, deswegen nehmen wir die!)

Die Variablen lesen wir ein und machen diese aktiv, daraufhin säubern wir nochmal alles und erstellen unsere CA (Certificate Authority, unsere Stelle zum Zertifikate ausstellen):

cd /home/openvpn/openvpn-ca
source vars
./clean-all
./build-ca

Hier kommt uns zugute dass wir dank der Datei ‘vars’ schon alle Daten als Umgebungsvariablen gesetzt haben, deshalb müssen wir eigentlich nur noch ENTER drücken bei den Abfragen.

Nun brauchen wir den Server Schlüssel, einen Diffie-Hellmann Schlüssel sowie eine HMAC-Signatur (bitte selber googeln wer genau wissen will was das ist…):

./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.key

Jetzt erzeugen wir ein Benutzerzertifikat für den Benutzer ‘client1’:

cd /home/openvpn/openvpn-ca
source vars
./build-key client1

Nachdem wir nun jetzt also viele Keys und Zertifikate haben kopieren wir diese zum OpenVPN, holen uns die Beispielkonfiguration und passen diese an:

cd /home/openvpn/openvpn-ca/keys
sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
sudo gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
sudo vi /etc/openvpn/server.conf

Unter ‘tls-auth ta.key 0’ schreiben wir direkt drunter:

key-direction 0

Und unter ‘cipher AES-256-CBC’ schreiben wir direkt drunter:

auth SHA256

Beim folgenden entfernen wir die Semikolons am Zeilenanfang damit die Werte aktiv werden:

user nobody
group nogroup

Jetzt sorgen wir noch dafür dass auch die DNS Abfragen unserer OpenVPN Clients von uns mit dem Dienst von OpenDNS beantwortet werden, folgende Zeilen auskommentieren:

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Tun wir das nicht so könnte ein Netzwerk in dem unser Client sitzt noch unsere DNS Abfragen mitkriegen. Das wollen wir natürlich nicht, denn die Abfrage nach der IP von www.tollercatcontent.de soll uns ja nicht verraten!
(Ja, die Domain ist noch frei, wer will kann sie sich jetzt hier schnappen und mir für meinen Tipp 20% aller Gewinne die die Domain erwirtschaftet abgeben!)

Jetzt müssen wir noch einstellen dass wir TCP und Port 443 wollen:

port 443
proto tcp
;proto udp

Und da folgendes im TCP-Modus nicht geht müssen wir es auskommentieren, indem wir ein ‘#’ an den Zeilenanfang schreiben:

#explicit-exit-notify 1

Die verwendeten Zertifikate stehen hier auch drin und müssten schon stimmen:

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

Damit sind wir mit der Config-Datei fertig. Jetzt müssen wir noch die Datei ‘/etc/sysctl.conf’ kurz anpassen (‘sudo vi /etc/sysctl.conf’) und dort eintragen/auskommentieren:

net.ipv4.ip_forward=1

Damit die Datei aktiv wird lesen wir sie wie folgt neu ein:

sudo sysctl -p

Jetzt müssen wir uns um die Firewall kümmern, dazu finden wir mit dem Befehl ‘ip route | grep default’ raus wie unser primäres Interface heißt:

default via 123.123.123.123 dev eth0 proto static

-> Das primäre Interface ist hier also eth0, diese brauchen wir in den folgenden Zeilen die wir mittels ‘sudo vi /etc/ufw/before.rules’ an den Anfang der Datei ‘sudo vi /etc/ufw/before.rules’ schreiben:

OPENVPN START
# NAT Rule
*nat
:POSTROUTING ACCEPT [0:0]
# Routing vom VPN Client zum primären Interface
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
### OPENVPN ENDE

Nun noch in der Datei ‘/etc/default/ufw’ eintragen/umstellen (‘sudo vi /etc/default/ufw’):

DEFAULT_FORWARD_POLICY="ACCEPT"

Und zu guter letzt den Port in der Firewall öffnen und unseren VPN-Server starten:

sudo ufw allow 443/tcp
sudo ufw allow OpenSSH
sudo ufw disable
sudo ufw enable

sudo systemctl start openvpn@server
sudo systemctl status openvpn@server

(‘sever’ ist unser ausgewählter Servername, es gibt eine entsprechende Datei ‘/etc/openvpn/server.conf’)

Wir sollten nun mit dem Kommando ‘ip addr show tun0’ ein Tunnel-Interface sehen:

3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
link/none 
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::fef9:xxxx:xxxx:xxxx/64 scope link stable-privacy 
valid_lft forever preferred_lft forever

Wenn das alles geklappt hat und OpenVPN als ‘active’ angezeigt wird und das Tunnel-Interface da ist können wir den OpenVPN Dienst direkt beim Start des Servers mitstarten lassen:

sudo systemctl enable openvpn@server

Nun müssen wir nur noch die Config für den Client erzeugen. Hier nehmen wir als Remote-Adresse die Domain ‘meintollesvpn.de’, welche wir bei DigitalOcean als Domain hinterlegt haben und dort den A-Eintrag mit einer TTL von 60 konfiguriert haben (gemietet habe ich die Domain bei Hetzner und dort die autoritären Nameserver auf die von DigitalOcean gestellt, dann habe ich die Domain bei DigitalOcean auf den DNS-Server angelegt).
Durch die niedrige TTL von 60 können wir sicher sein dass ein Ändern des A-Eintrages der Domain möglichst schnell aktiv wird. Den A-Eintrag müssen wir jedesmal anpassen wenn sich die IP unseres OpenVPN-Servers ändert, und das tut sie jedesmal wenn wir ihn neu aus unserem Snapshot erstellen!

Kopieren der Beispielconfig:

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
vi /home/openvpn/client-configs/base.conf

Und wie folgt anpassen:

proto tcp
;proto udp

remote meintollesvpn.de 443

user nobody
group nogroup

#ca ca.crt
#cert client.crt
#key client.key

#tls-auth ta.key 1

cipher AES-256-CBC
auth SHA256
key-direction 1

(Die auskommentieren key-Files kommentieren wir aus weil wir diese direkt in die Config-Datei mit reinschreiben und diese somit nicht als extra Datei nötig sind!)

Jetzt bietet uns René Fürst ein kleines Script welches wir verwenden können um alle Zertifikate in die Config-Datei mit einzufügen, bekommen tun wir es wie folgt:

cd /home/openvpn/client-configs
wget https://www.renefuerst.eu/downloads/make_config.sh.txt -O make_config.sh

Aussehen tut es so:

#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn

Also schnell ausführbar machen und ausführen:

chmod 700 make_config.sh
./make_config.sh client1

Es befindet sich nun in diesem Ordner die Datei ‘client1.ovpn’, welche die nötige Konfigdatei für jeden OpenVPN Client ist!

/home/openvpn/client-configs/files

Diese Datei können wir z.B. auf unser Handy schicken und dort damit die OpenVPN App füttern. Schon sind wir im VPN drin. Testen kann man das sehr einfach mit dem Aufruf von z.B. https://www.wieistmeineip.de, denn dort sollte vor dem VPN-Aufbau eine andere IP (die IP des aktuellen Netzwerks) stehen als danach, danach ist es nämlich die IP (und der Standort) unsere OpenVPN Servers.

Unter Linux kann man OpenVPN mit der Datei z.B. wie folgt starten:

sudo apt-get install openvpn
sudo mv client1.ovpn /etc/openvpn
cd /etc/openvpn
sudo openvpn client1.ovpn

Das letzte was jetzt noch bleibt ist die virtuelle Maschine (Droplet) bei DigitalOcean in einen Snapshot zu verpacken. Diesen Snapshot können wir noch in jedes Rechenzentrum von DigitalOcean kopieren (dauert ca. 5 Minuten pro Rechenzentrum, kostet aber nichts extra) und können somit jederzeit aus dem Snapshot eine neue virtuelle Maschine in jedem gewünschten Rechenzentrum erstellen. Nach dem starten der virtuellen Maschine muss nur noch der A-Eintrag der Domain ‘meintollesvpn.de’ bei DigitalOcean auf die neue IP des neuen Servers gestellt werden und schon geht alles.

Der eingepackte Snapshot hat bei mir übrigens 1.51 GB und kostet ca. 8 $-Cent im Monat.

Ja, ich weiß… OpenVPN ist doch etwas kompliziert. Und das alles nur für ein paar Katzenbilder.

Aber es geht bekanntlich ums Prinzip 🙂

PS: Die Verwendung der Befehle und der Script-Datei von René Fürst wurden mir genehmigt. Vielen Dank hierfür!

4 Antworten auf „Weltweit flexibles VPN dank OpenVPN und DigitalOcean“

  1. OpenVPN ist umständlich hoch zehn 🙂

    Ein vollständiges VPN für Alle erreicht man mit 5 SSH Anweisungen 😀 Dein Laptop routet dann noch das Handy und gut 😉

    Grüße aus Braunschweig

    1. Hallo Marius,

      super coole Sache!

      Nur wie krieg ich dann einfach mein Handy über den Laptop geroutet? Der müsste ja ein WLAN fürs Handy aufmachen während er gleichzeitig im WLAN des Hotels eingebucht ist. Geht das mit normalen Wlan-Interfaces problemlos? (Der ESP8266/ESP32 kann das, deshalb kann es eigentlich nicht so schwer sein…)

      Thomas

      PS: Hier nochmal der Link deutlich für alle: https://marius.bloggt-in-braunschweig.de/2016/04/12/ssh-vpn-mit-den-iproute2-tools/

      1. Ja, fairerweise muß man sagen, daß wird schwierig 😉 Ein kleiner USB-WIFI Stick könnte das Problem elegant lösen. In die andere Richtung ist das deutlich einfacher, weil man das Handy ja als USB-WIFIAdapter ansprechen kann. Da wäre der AP auf dem Laptop dann kein Problem mehr.(Ratet mal wie die Wifi-Fallen im Cafe funktionieren 😉 )

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.