openvpn für "Altlasten"



Vorwort


Mit den Auswirkungen der IPv4-Adressknappheit haben immer mehr Internetnutzer zu kämpfen.
Dies äußert u.a. in der größer werdenden Verbreitung von CGNAT, das sich auch hinter wohlklingenden Bezeichnungen wie Dualstack-lite versteckt. Adressüberlappungen und der Verlust der direkten Adressierbarkeit sind die Folgen.

Glücklicherweise bieten fast alle InternetServiceProvider, die ihren Kunden keine eigene IPv4-Adresse mehr bieten können, vollständige IPv6-Konnektivität.

Damit kann man etwas anfangen. Man kann z.B. privaten IPv4-Verkehr tunneln.

Eigentlich sollte diese Anleitung überflüssig sein, jedenfalls, wenn man eine Fritzbox sein eigen nennt. Dem ist leider nicht so. Das Leistungsmerkmal "VPN" von AVM ist nicht vollumfänglich Internet-tauglich.

Wozu also der Aufwand?

Es gibt ja schließlich direkte Konnektivität via IPv6. Myfritz als DNS-Service von AVM bietet hier hervorragende Dienste.

Das Problem


Die Fon-App von AVM funktioniert nur richtig mit VPN (Telefonieren zum Festnetztarif).
Einige Internetnutzer haben alte IPv4-Geräte, z.B. Webcams, NAS und frühe Implementationen von Heimautomatisierung.

Die Idee zur Lösung


openvpn: Transportnetz via IPv6, Payload(Nutzlast) IPv4(privat) und IPv6(wahlweise local oder global unicast).


Umsetzung


Hardware: Raspberry PI (im Grunde geht auch jeder andere Rechner) der Raspberry Pi bietet sich an, weil er leise, stromsparend und relativ günstig ist.

Software: Linux (hier openSUSE Tumbleweed, debian oder raspbian sollten ebenso ihren Zweck erfüllen)

openvpn ist sehr komplexe Software. Ein meiner Meinung nach sehr aufwendiger Teil ist die Erstellung entsprechender Verschlüsselungszertifikate. Dazu verweise ich nur auf die mitgelieferte Dokumentation.
Die einfache Variante mit dem "static.key" ist zwar sehr verlockend, hat aber letztendlich zu viele Einschränkungen.


Der VPN-Service läuft also auf dem Raspberry Pi, ganz normal via LAN-Kabel angeschlossen.
Der Raspberry Pi hat eine IPv6-Adresse, die auf der Fritzbox freigegeben(Firewall) ist und außerdem via myfritz einen stabilen Servernamen hat. (andere Router und DDNS-Dienste sind hier auch denkbar)

Um statische Routeneinträge auf dem Router und den anderen Geräten zu vermeiden, setze ich auf ARP-Proxy und NDP-Proxy.

sysctl net.ipv4.conf.eth0.proxy_arp=1
sysctl net.ipv6.conf.eth0.proxy_ndp=1




Da der Raspberry Pi ja nun Pakete zwischen tun0 und eth0 routen soll, ist noch folgende Einstellung notwendig:

sysctl net.ipv4.ip_forward=1
sysctl net.ipv6.conf.all.forwarding=1


ip neigh add proxy fd00::1:1001 dev eth0
ip neigh add proxy fd00::1:1002 dev eth0
ip neigh add proxy fd00::1:1003 dev eth0


leider für jede IPv6-Adresse einzeln,
oder via diesem Shellaufruf einfach mal für alle setzen:

for i in $(seq 0 65535) ; do ip neigh add proxy fd00::1:$(printf %x $i) dev eth0; done



Für IPv6 kann man auch noch auf ein richtiges geroutetes Netz setzen (die Fritzbox unterstützt dhcpv6-pd). Das hätte den Vorteil, dass man die Adressen auch zum Verkehr mit der Welt nutzen könnte, aber den Nachteil, dass das dynamische Präfix auch dynamisch in openvpn konfiguriert werden müsste.
Im hier hinterlegten Skript umgehe ich das dhcp-problem und nutze auch die global unicast Adressen via NDP-Proxy. Wegen der dynamischen Präfixe muss das Skript nach jedem Wechsel neu aufgerufen werden.


Unter der Annahme, dass die Fritzbox nur den Adressbereich von 192.168.178.20-192.168.178.200 nutzt,

bekommt der VPN-Server 192.168.178.200/29

Nach einer Verkleinerung des DHCP-Bereichs (192.168.178.20-192.168.178.127) verwende ich nun 192.168.178.128/25.


Somit sieht die Serverkonfiguration (server.ovpn) so aus:

proto udp6
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 192.168.178.128  255.255.255.128
server-ipv6  fd00::1:1/112
push "route 192.168.178.0 255.255.255.0"
push "route-ipv6 fd00::/64"
keepalive 10 120
verb 3


Auf dem Client (client.ovpn) sieht das so aus:

client
dev tun
proto udp6
remote servername-hier-nicht-abschreiben 1194 udp6
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
verb 3


Mit diesen Einstellungen kann man nun die Konfigurationsoberfläche der Fritzbox unter http://192.168.178.1 (oder http://[fd00::3631:c4ff:fef8:83a4] )aufrufen, auch andere IPv4-Geräte im "Heimnetz" sind somit aus der Ferne wieder erreichbar.
Als Client habe ich einmal ein Linux-Notebook via Freifunk München und einmal OpenVPN auf Android via Mobilfunk (Deutsche Telekom) genutzt.
Nach Setzen der DNS-Optionen(siehe Skript) klappt auch der Aufruf von http://fritz.box

Dieses veröffentlichte Selbstgespräch erhebt keinen Anspruch auf Fehlerfreiheit. Lob und Kritik sind trotzdem willkommen.

Thomas Schäfer

Februar 2017

Nachtrag vom Oktober 2020:

OpenVPN verwendet ab Version 2.5 gleich den Anfang des vorgegebenen IPv6-Pools. Bei Verwendung des Vodafonemobilfunknetzes (Client) gibt es per UDP einige Probleme. Daher nutze ich der Server seit geraumer Zeit via TCP. (Skript)