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!
Schreibe einen Kommentar