OpenVPN Server mit IPv4 und IPv6

Ich nutze schon länger einen eigenen VPN Server auf Basis von OpenVPN um meinen Internettraffic in öffentlichen, nicht vertrauenswürdigen Netzwerken zu verschlüsseln. Dieser hat allerdings nur einen IPv4 Tunnel unterstützt. Meine wenig zufriedenstellende Lösung für dieses Problem war immer das deaktivieren von IPv6 in solchen Situationen, um sicherzustellen dass keine Daten über die IPv6 Verbindung am VPN vorbei gelangen.

Da ich diese Situation für nicht akzeptabel hielt habe ich schon länger versucht den Server so zu konfigurieren dass der Client auch eine IPv6 Adresse erhält und IPv6 Traffic durch den VPN Tunnel geleitet wird.

Der einfachste Weg dies zu realisieren war lange Zeit die Nutzung der OpenVPN kompatiblen VPN Software pritunl. Pritunl lässt sich schnell einrichten, lässt sich einfach über ein Webinterface konfigurieren und unterstützt auch IPv6.
Allerdings war Pritunl bei mir nie so zuverlässig wie mein alter OpenVPN Server. Außerdem vergibt Pritunl keine öffentlichen IPv6 Adressen an die Clients sondern, sondern private und leitet den Traffic via NAT über die öffentliche Adresse des Servers. Aus diesem Grund war ich mit Pritunl leider auch nicht zufrieden.

Meine Wunsch war der Aufbau eines Tunnels über IPv4 (da eine IPv4 Verbindung i.d.R. immer vorhanden ist). Außerdem sollte darüber der IPv6 Traffic getunnelt werden und die Clients sollen eine öffentliche IPv6 Adresse aus dem /64 des Servers erhalten

Aus diesem Grund habe ich, glaube ich, sämtliche Webseiten die Google zum Suchbegriff „Openvpn IPv6“ ausspuckt gelesen und viele Konfigurationen ausprobiert. Letztendlich haben mich zwei Seiten auf die richtige Spur zu einer für mich funktionierenden Konfiguration gebracht. Einmal ein Beitrag aus dem Openvpn Forum und ein Blogbeitrag auf techblog.synagila.com.

Da allerdings beide Artikel bei mit nicht 1:1 funktioniert haben, beschreibe ich hier meine Konfiguration, wie sie für mich auf einem Root-Server (Produktname) von Netcup und Ubuntu Server 16.04 funktioniert.

Ich gehe in diesem Beispiel davon aus dass folgende (fiktive) IP Adressen/Bereiche vorliegen, bzw konfiguriert sind:

Öffentliche IPv4 Adresse des Servers: 84.154.165.64
Zugeteilter IPv6 Adressbereich: 2003:6a:6b09:3a00::/64
Konfigurierte IPv6 Adresse des Servers: 2003:6a:6b09:3a00:aaaa::10
Für das VPN verwendete IPv6 Subnetz: 2003:6a:6b09:3a00:bbbb::/112

Paketinstallation

Zuerst wird Openvpn und Easy-RSA zur Schlüsselverwaltung installiert

sudo apt install openvpn easy-rsa

Schlüsselerstellung

Um die weiteren Befehle direkt ausführen zu können wird zu User root gewechselt

sudo -i

Dann werden die Beispielskripte von easy-rsa zur Schlüsselerzeugung in das Openvpnverzeichnis kopiert und dort der Ordner Keys erstellt.

cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
mkdir keys

Dann können die Standardwerte zur Schlüssel und Zertifikatserstellung in der Datei vars geändert werden, damit diese Daten bei der Erzeugung von Schlüsseln und Zertifikaten bereits voreingestellt sind. Dazu wird die Datei in einem Texteditor geöffnet und folgende Daten angepasst:

nano vars
export KEY_COUNTRY="LAND"
export KEY_PROVINCE="BUNDESLAND"
export KEY_CITY="STADT"
export KEY_ORG="ORGANISATION"
export KEY_EMAIL="name@example.com"
export KEY_OU="ABTEILUNG"

# X509 Subject Field
export KEY_NAME="server"

Damit OpenVPN die gerade geänderten Variablen bei der Erstellung der Zertifikate verwendet müssen diese in die aktuellen Umgebungsvariablen aufgenommen werden. Dieser Befehl muss dementsprechend wieder ausgeführt werden wenn später nach einem Reboot weitere Schlüssel und Zertifikate erstellt oder widerrufen werden sollen.

source ./vars

Dann werden evtl. vorhandene alte Schlüssel entfernt und die CA (certificate authority) erstellt, mit welcher anschließend die neuen Zertifikate signiert werden.

./clean-all
./build-ca

Dann können Serverschlüssel und Zertifikat erstellt werden mit

./build-key-server server

Die Abfrage nach einem Passwort kann mit Enter übersprungen werden. Die Abfragen am Ende zweimal mit „y“ bestätigen.

Dann können Zertifikate und Schlüssel für die Clients erstellt werden. Hier muss im Feld „common name“ ein Name für den Clients eingegeben werden.

./build-key clientname1
./build-key clientname2
./build-key clientname3

Nun müssen noch die Diffie-Hellman-Parameter generiert werden, mit denen Schlüssel sicher über unsichere Kanäle ausgehandelt werden können

./build-dh

Zum Schutz vor DOS Atacken kann nun noch der Signierungsschlüssel ta.key erstellt werden. Wenn dessen Nutzung konfiguriert ist werden alle Anfragen an den Server hiermit signiert. Nicht signierte Anfragen werden vom Server direkt verworfen, was Ressourcen spart und DOS Attacken vorbeugt.

openvpn --genkey --secret keys/ta.key

Die Zertifikate und Schlüssel für den Server und die Clients sind nun unter /etc/openvpn/easy-rsa/keys gespeichert.
Nun können die Schlüssel auf die entsprechenden Computer transferiert werden. Aus Sicherheitsgründen sollten auf jedem Computer nur die benötigten Dateien zu finden sein.
Der Server benötigt die server.key, server.crt, die ca.crt, dh2048.pem sowie die ta.key.

Die Clients benötigen die clientname1.key clientname1.crt die ca.crt sowie die ta.key.

OpenVPN Server konfigurieren

Als erstes wird der User „openvpn“ erstellt, welcher den OpenVPN Dienst ausführt damit dieser nicht als Root läuft.

addgroup --system --no-create-home --disabled-login --group openvpn
adduser --system --no-create-home --disabled-login --ingroup openvpn openvpn

Dann muss dem Kernel das weiterleiten von Traffic vom Client zum Internet erlaubt werden, indem die folgenden Zeilen in der /etc/sysctl.conf an Ende eingefügt, oder angepasst werden:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.proxy_ndp = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

und die iptables Regeln für IPv4 und IPv6 gesetzt werden. Hier muss evtl. der Name des verwendeten Netzwerkinterfaces angepasst werden sowie das vom Serveranbieter zugewiesene /64 subnet angepasst werden. Dann werden folgende Befehle nacheinander ausgeführt:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP
ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp -j ACCEPT
ip6tables -A FORWARD -s 2003:6a:6b09:3a00::/64 -j ACCEPT
ip6tables -A INPUT -j REJECT

Damit die Regeln nach einem Neustart wieder aktiv sind, werden die aktuellen iptables Regeln zuerst in eine Datei exportiert:

iptables-save > /etc/iptables.rules
ip6tables-save > /etc/ip6tables.rules

Diese werden dann nach einem Neustart wieder geladen, indem in die Datei
/etc/network/if-up.d/iptables mit folgendem Inhalt angelegt wird:

#!/bin/sh
iptables-restore < /etc/iptables.rules
ip6tables-restore < /etc/ip6tables.rules

Diese muss dann noch ausführbar gemacht werden

chmod +x /etc/network/if-up.d/iptables

Über die Kernel Parameter wurde oben festgelegt dass der Server als NDP (Neighbor Discovery Protocol) Proxy fungiert. Die NDP Proxy Regeln für die Openvpn Clients werden indem die Datei /etc/openvpn/scripts/ndp-proxy-setup.sh mit folgendem Inhalt erstellt wird. Auch hier muss ggf. der Name des Netzwerkinterfaces geändert werden.

#!/bin/bash

action="$1"
addr="$2"
pubif="eth0"

if [[ "${addr//:/}" == "$addr" ]]
then
    # not an ipv6 address
    exit
fi

case "$action" in
    add)
        ip -6 neigh add proxy ${addr} dev ${pubif}
        ;;
    update)
        ip -6 neigh replace proxy ${addr} dev ${pubif}
        ;;
    delete)
        ip -6 neigh del proxy ${addr} dev ${pubif}
        ;;
esac

auch dieses Skript muss nun noch ausführbar gemacht werden

chmod 744  /etc/openvpn/scripts/ndp-proxy-setup.sh

Da OpenVPN aus Sicherheitsgründen nicht als root laufen soll, die oben definierten Einstellungen aber nur von root vorgenommen werden dürfen, muss dem User openvpn erlaubt werden diese eine Datei mit Rootrechten ausführen zu dürfen. Zur Konfiguration der /etc/sudoers wird diese mit dem Befehl

visudo

geöffnet und folgende Zeilen eingefügt

# OpenVPN
openvpn ALL=NOPASSWD: /etc/openvpn/scripts/ndp-proxy-setup.sh

Letztendlich muss nur noch die eigentliche Serverkonfiguration für den OpenVPN Server selbst erstellt werden. Dazu wird die Datei /etc/openvpn/server.conf mit untenstehendem Inhalt erstellt. Dabei muss an den entsprechenden Stellen wieder das /64 IPv6 Prefix welches man von seinem Serveranbieter erhalten hat angepasst werden.

port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
dh /etc/openvpn/easy-rsa/keys/dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
server-ipv6 2a03:4000:6:11cd:bbbb::/112
ifconfig-pool-persist ipp.txt
push "route-ipv6 2000::/3 2a03:4000:6:11cd:bbbb::1 1"
script-security 2
learn-address "/usr/bin/sudo -u root /etc/openvpn/scripts/ndp-proxy-setup.sh"
push "redirect-gateway def1"
push "redirect-gateway ipv6"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256:TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
auth SHA512
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 6
user openvpn
group openvpn

Dann wird noch der Autostart von Openvpn über Systemd aktiviert, wobei der Teil server in diesem Befehl der Name unserer server.conf Datei ist. Wäre diese anders benannt, oder hätten wir mehrere Konfigurationen müsste der Befehl angepasst werden.

systemctl enable openvpn@server.service

Noch eine kurze Anmerkung falls die Firewall UFW verwendet wird. Diese verhindert in der Standardeinstellung dass Pakete weitergeleitet werden. Um dies zu erlauben muss in der etc/default/ufw die DEFAULT_FORWARD_POLICY auf ACCEPT geändert werden.

Um Sicherzustellen dass alle Konfigurationen übernommen wurden sollte der Server einmal mit einem beherzten „reboot“ neugestartet werden.

Client konfigurieren

Die Konfigurationsdatei client.ovpn, welche auf den Clients benötigt wird sieht wie folgend aus. Hier muss die öffentliche IPv4 Adresse des Servers angepasst werden, sowie ggf. die Namen und Pfade zu den Schlüsseln und Zertifikaten auf dem Clientcomputer.

client
dev tun
proto udp
remote 84.154.165.64 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256:TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
auth SHA512
comp-lzo
verb 6
explicit-exit-notify

Anschließend kann im Terminal eine Verbindung zum OpenVPN Server aufgebaut werden mit:

sudo openvpn /pfad/zur/client.conf

Um zu testen ob das VPN funktioniert kann z.B. die Seite http://test-ipv6.com aufgerufen werden. Die erkannte IPv4 Adresse muss nun die öffentliche IP des Servers sein. Die erkannte IPv6 Adresse muss aus dem Pool des Servers stammen.

Zur Konfiguration von weiteren (grafischen) Clients möchte ich gerne auf meine älteren Artikel verweisen.

OpenVPN Client unter Ubuntu (Desktop) einrichten

OpenVPN Client unter Windows einrichten (in dieser Konfiguration ungetestet)

OpenVPN Client unter Android einrichten



88x31_CC_by
Dieser Text ist lizensiert unter einer Creative Commons Namensnennung 4.0 International Lizenz.
Titelbild „netzwerk-server-internet-2081171“ von Pixabay steht unter Creative Commons CC0

6 Kommentare

  • Hi,
    danke für die Anleitung. Suche schon seit einem Jahr nach so etwas.

    Für mich war die Konfiguration jedoch minimal anders, da mein Client auf iOS läuft und immer folgenden Fehler geworfen hat: „tun_prop_route_error: route destinations other than vpn_gateway or net_gateway are not supported“

    Konnte den fehler durch Ändern von
    – push „route-ipv6 2000::/3 2a03:4000:6:11cd:bbbb::1 1“
    in
    – push „route-ipv6 2000::/3“
    beheben.

    Vielleicht hilft diese Info ja jemandem.

    Viele Grüße

  • Daniel Wilhelm

    1A Anleitung! Top!
    Musste nur die Cipher Liste anpassen wegen zu alter OpenVPN Client Version.
    Wenn du Donations via PayPal nimmst, sag bitte Bescheid!

    Grüße,
    Daniel

  • Super Anleitung. Freue mich schon das auszuprobieren. Werde mich zurückmelden. Wenn’s klappt würde ich direkt mal den Ubuntuusers.de-Artikel zu OpenVPN anpassen.

  • Hallo,

    danke für die Anleitung. Leider bekomme ich keine Verbindung zum Server hin.
    Der Client für Android gibt folgende Meldung aus:

    2017-03-26 17:41:06 TCP/UDP: Preserving recently used remote address: [AF_INET]81.169.168.7:1194
    2017-03-26 17:41:06 Socket Buffers: R=[212992->212992] S=[212992->212992]
    2017-03-26 17:41:06 MANAGEMENT: CMD ’needok ‚PROTECTFD‘ ok‘
    2017-03-26 17:41:06 UDP link local (bound): [AF_INET][undef]:1194
    2017-03-26 17:41:06 UDP link remote: [AF_INET]81.169.168.7:1194
    2017-03-26 17:41:06 MANAGEMENT: >STATE:1490542866,WAIT,,,,,,
    2017-03-26 17:42:06 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
    2017-03-26 17:42:06 TLS Error: TLS handshake failed
    2017-03-26 17:42:06 TCP/UDP: Closing socket
    2017-03-26 17:42:06 SIGUSR1[soft,tls-error] received, process restarting

    http://pastebin.com/pMu1FvZN

  • Ich überlegte schon länger, mir sowas mal zu bauen. Herzlichen Dank! Ob ich es nun wirklich mal angehe, weiß ich zwar immer noch nicht genau, aber es reduziert zumindest schon deutlich meine bisherige Ablehnung, die sich aus dem drohenden, hohen Aufwand ergab, das alles in meiner spärlichen Freizeit durchzuarbeiten und auszuprobieren.

  • MM

    Interessant, hab vielen Dank für deine Anleitung! Ich hatte vor ca. einem Jahr schon mal selbst einen Versuch unternommen, um OpenVPN unter OpenWRT auf meinem Router ans Laufen zu bekommen. Leider hat das trotz mehrmaliger Anläufe nicht funktioniert, wahrscheinlich auch, weil die Anleitungen und Ansätze sich teilweise stark wiedersprechen und ja doch einige Komponenten in einander greifen müssen:
    https://wiki.openwrt.org/doc/howto/vpn.openvpn
    https://wiki.openwrt.org/inbox/vpn.howto
    https://wiki.openwrt.org/doc/howto/vpn.server.openvpn.tun

Schreibe einen Kommentar

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