Android-Geräte dem VPN hinzufügen und IPv6

Im letzten Blogpost habe ich beschrieben, wie ich mein privates Netz mit openVPN aufbaue. In diesem Post möchte ich zeigen, wie man Android-Geräte dem Netz hinzufügen kann, und was ich tun musste, damit der Server korrekt auf IPv4 und IPv6-Anfragen lauscht.
openvpn
Heimserver
IPv6
ubuntuusers
Autor:in

Joe Slam

Veröffentlichungsdatum

19 März 2024 - 09:24

Geändert

31 März 2024 - 20:00

Im letzten Blogpost habe ich beschrieben, wie ich mein privates Netz mit openVPN aufbaue. In diesem Post möchte ich zeigen, wie man Android-Geräte dem Netz hinzufügen kann, und was ich tun musste, damit der Server korrekt auf IPv4 und IPv6-Anfragen lauscht.

IPv6

Mein Heimserver, der die VPNs aufbaut, ist sowohl per IPv4 als auch per IPv6 erreichbar. Da das Mobilnetz an Handy und Tablet fast ausschließlich IPv6 nutzt, ist es eine gute Idee, auf beiden Netzen zu lauschen. Damit der openVPN-Server sowohl per IPv4 als auch per IPv6 auf Anfragen antwortet, ändere ich in der Server-Config die Stelle

proto udp

auf

proto udp6

UDP6 antwortet mit anderer Adresse

Bei mir gab es das Problem, dass udp6 nicht mit der IP-Adresse auf Anfragen antwortet, an welche die Anfrage abgeschickt wurde. Mein Server hat beispielsweise die feste IPv6 2002:bla:fasel::4/64. Mein Handy sendet nun aus dem Mobilnetz (da gibt es nur IPv6) an diese Adresse seine Anfrage, aber der Server antwortet mit einer neuen IPv6, z.B. 2002:bla:fasel:ätschi:bätsch:4/64. In diesem Falle kommt keine Verbindung zu Stande (das scheint schon länger und immer wieder ein Problem mit UDP zu sein).

Die Lösung besteht darin, in der Server-Config die Zeile multihome zu ergänzen.

proto udp6
multihome

Die Option stellt sicher, dass die UDP-Antwortpakete immer von der Adresse gesendet werden, an welche der Client seine Anfragen gestellt hat.

IPv6-ULA einrichten.

Bislang bekommen alle Clients eine IP4 aus dem 10.5.5.0/24 Bereich, wobei ich über das ccd-Verzeichnis jedem Client eine feste IP gegeben habe. Da ich den Server nun auch aus dem IPv6-Netz heraus erreichbar gemacht habe, verteile ich über mein VPN zusätzlich IPv6-ULA-Adressen aus dem Bereich fd04:bab0::/64, so dass alle Clients auch per IPv6 ansprechbar sind.

Hierfür ergänze ich die Server-Config um folgende Zeilen:

server-ipv6 fd04:bab0::/64        # ULA IPv6 Subnetz für OpenVPN-Clients
push "route-ipv6 fd04:bab0::/64"  # ULA IPv6 Subnetz an die Clients weitergeben

Ebenfalls ergänze ich im ccd-Verzeichnis die Dateien aller Clients um folgende Zeile:

ifconfig-ipv6-push fd04:bab0::xyz/64

wobei ich für xyz jeweils die selbe Ziffer nehme wie im IPv4 Netz.

Nach einem Neustart des VPN-Servers erhalten alle Clients automatisch eine 10.5.5.0/24 sowie eine fd04:bab0::/64-Adresse und können sich gegenseitig über IPv4 oder IPv6 anpingen. An den Client-Configs muss nichts geändert werden.

IPv6 Internet durch den Tunnel routen

Damit auch das globale IPv6-Internet durch den Tunnel geroutet werden kann, müssen die Firewallregeln angepasst werden.

iptables

# iptables
ip6tables -t nat -D POSTROUTING -s fd04:bab0::/64 -o eth0 -j MASQUERADE

ufw

Für IPv6 muss die Datei /etc/ufw/before6.rules angepasst werden. Füge die folgenden Zeilen vor der *filter-Sektion ein, um das NAT für IPv6 zu aktivieren:

nano /etc/ufw/before6.rules

# NAT-Tabelle hinzufügen
*nat
:POSTROUTING ACCEPT [0:0]
# OpenVPN-Regeln hinzufügen
-A POSTROUTING -s fd04:bab0::/64 -o eth0 -j MASQUERADE
COMMIT

Zertifikate erstellen

Damit Handy und Tablet das VPN nutzen können, benötigen sie wieder gültige Zertifikate und den ta.key des VPNs (siehe letzter Blogpost).

Dazu wechsle ich auf meine Zertifikationsinstanz und erstelle wie gewohnt Zertifiakte für Handy und Tablet, z.B. so:

sudo bash
cd /etc/easy-rsa
easyrsa gen-req handy nopass
easyrsa sign-req client handy

easyrsa gen-req tablet nopass
easyrsa sign-req client tablet

Zertifikat für Android umwandeln

Wir können Androids Zertifikateverwaltung nutzen, um die Zertifikate halbwegs “sicher” auf den Geräten zu verwalten. Hierfür bündeln wir

  • /etc/easy-rsa/pki/private/handy.key
  • /etc/easy-rsa/pki/issued/handy.crt
  • /etc/easy-rsa/pki/ca.crt

in einer PKCS-Datei mit dem Namen handy.p12, die wir dann später am Handy importieren können. Der dazugeöhrige Befehl lautet:

openssl pkcs12 -export -in CERT -inkey KEY -certfile CA -name CLIENTNAME -out OUTPUT.p12

In meinem Fall also

openssl pkcs12 -export -in pki/issued/handy.crt -inkey pki/private/handy.key -certfile pki/ca.crt -name handy -out handy.p12

Ihr werdet nach einem Export-Passwort gefragt. Denkt euch irgendetwas halbwegs sicheres aus. Am Handy muss später dieses Passwort beim Import eingegeben werden.

Die erzeugte PKCS-Datei handy.p12 sowie der ta.key des VPN müssen nun auf das Handy kopiert werden. Ich nutze hierfür meine Nextcloud, KDE Connect oder eine E-Mail an mich selbst.

  • Ist die Datei handy.p12 auf das Handy kopiert, klicke ich am Handy auf eben diese Datei, um die Zertifikate in den Android-Zertifikatespeicher aufzunehmen. Hierbei muss das oben erwähnte Passwort eingegeben werden.
  • Die Datei ta.key kopiere ich an eine Stelle meines Handys, die ich mir merken kann, z.B. “Dokumente/OpenVPN”

openVPN for Android

Für Android steht z.B. über F-Droid das Paket von blinkt zur Verfügung, siehe https://f-droid.org/packages/de.blinkt.openvpn/

  • In der Client-App erstelle ich ein neues Profil mit dem Namen “test” (Name ist ja egal).
  • Im Reiter “Basic” klicke ich bei “Client Certificate” auf den Select-Button. So kann ich das eben in Android importierte Zertifikat auswählen.

importierte Zertifikate im Androidspeicher
  • Im Reiter “Server List” trage ich meinen Server ein und wähle unter “Protocol” UDP.

Serveradresse und Protocol “UDP”
  • Unter dem Reiter “Authentication/Encryption” müssen folgende Einstellungen getroffen werden:
    • bei TLS-Settings entferne ich den Haken bei “Certificate Hostname Check”

kein “Certificate Hostname Check”
  • dafür setze ich den Haken bei “Use Control Channel Authentication/Encryption”
    • als “TLS Auth/TLS Encrpytion File” wähle ich den auf das Handy kopierten ta.key
    • als “Authentication/encryption method” wähle ich Encryption (--tls-crypt)

TLS Auth/TLS Encrpytion File ist ta.key und Encryption --tls-crypt
  • bei “Encryption ciphers” trage ich (gemäß meiner Server-Config) AES-256-CBC:AES-256-GCM ein.

Encryption ciphers auf AES-256-CBC:AES-256-GCM

Das funktioniert wunderbar, und mein Handy kann sich mit meinem VPN verbinden.

erfolgreich verbunden

Jetzt können sich alle Clients (auch die Mobilgeräte über IPv6) mit dem Server verbinden und sich gegenseitig anpingen.

gesamten Verkehr der Mobilgeräte über das VPN routen

Im Reiter “Routing” können bei Bedarf die Haken bei “Use default Route” für IPv4 und IPv6 gesetzt werden. Dann wird der gesamte Datenverkehr des Handys über das VPN geroutet. Die Server-Config muss dafür nicht angefasst werden.

alles übers VPN routen

Das ist sehr vorteilhaft, z.B. wenn man in einem ranzigen WLAN unterwegs ist (McDoof, Bahn, etc.) oder im Ausland dennoch “Sportschau” übers Netz schauen möchte. Auch funktioniert KDE Connect bestens über das VPN, was für meinen Büro-PC sehr gut ist.

Möchtet ihr auch bei anderen Clients (z.B. beim Laptop) den gesamten Datenverkehr durch das VPN routen, müsst ihr in dessen Client-Config folgende Zeile ergänzen:

redirect-gateway def1 # leitet gesamten Datenverkehr über das VPN

Das def1 steht für “default route” und muss nicht weiter angepasst werden. Nun läuft auch am Laptop alles über das VPN.