DualStack VPN mit Wireguard

Die neue VPN-Technik Wireguard reizte mich schon etwas länger. Sie hat den Ruf extrem performant und einfach einzurichten zu sein. Nun denn …

Ich versuchte zunächst das Beispiel auf der offiziellen Webseite zu verstehen und nachzubauen. Eine recht wichtige Erkenntnis dabei ist, dass Wireguard primär dafür gemacht ist, Netze mit einander zu verbinden. Es fehlen Funktionen wie ein DHCP-Server für die VPN-Clients oder auch DNS-Search-Domains. Dafür bietet es extreme Performance.
Mein primäres Ziel war es aber von unterwegs auf mein Heimnetz zugreifen zu können und ggf. auch komplett über zuhause ins Internet zu gelangen. Dies Entspricht eher einem Client-Server-Szenario. Hierbei hat mir die Dokumentation von Ubuntu sehr gut weiter geholfen.
Ich startete mit der Installation auf einem Debian.
Danach wurden die Private-Keys und die daraus resultierenden Public-Keys generiert, so wie ein gemeinsamer Preshared-Key:

wg genkey > server_private.key
wg pubkey < server_private.key > server_public.key
wg genpsk > psk.key

wg genkey > client_1_private.key
wg pubkey < client_1_private.key > client_1_public.key

wg genkey > client_2_private.key
wg pubkey < client_2_private.key > client_2_public.key

Rätselhaft war mir aber, welche Befehle und Konfigurationsmöglichkeiten denn zur verfügung stehen. Die Dokumentation dazu konnte ich nicht finden, jedoch hat mir diese Veröffentlichung viel weiter geholfen.
Ich entschied mich dazu, die Wireguard Config des Servers in die /etc/network/interfaces zu integrieren:

auto wg0
iface wg0 inet static
  address 192.168.20.5
  netmask 255.255.255.0
  pre-up ip link add wg0 type wireguard
  pre-up wg setconf wg0 /etc/wireguard/wg0.conf
  up ip link set wg0 up
  down ip link delete wg0
iface wg0 inet6 static
  address fd00::20:1
  netmask 64

Hier wird dem Server die IP 192.168.20.5 gegeben und außerdem die Wireguard-config aus /etc/wireguard/wg0.conf geladen. Diese sieht dann z.B. so aus:

[Interface]
PrivateKey = < private Key des Servers >
ListenPort = 51820

[Peer]
PublicKey = < public Key des Client 1 >
PresharedKey = < private Key des PSK >
# dies sind die IPs des Client 1:
AllowedIPs = 192.168.20.10/32, fd00::20:10/128

[Peer]
PublicKey = < public Key des Client 2 >
PresharedKey = < private Key des PSK >
AllowedIPs = 192.168.20.20/32, fd00::20:20/128

Und die dazugehörige Client-config von Client 1:

[Interface]
PrivateKey = < private Key des Clients >
Address = 192.168.190.10/32, fd00::20:10/128

[Peer]
PublicKey = < public Key des Servers >
PresharedKey = < private Key des PSK >
# diese Netze gehen über die VPN-Verbindung:
AllowedIPs = 192.168.20.0/24, fd00::20:/64
# Port-Forwarding bzw. Freigabe nicht vergessen:
Endpoint = vpn.meinedomain.de:51820
# dies sorgt bei Firewalls mit Connection-Tracking für den Erhalt der Verbindung:
PersistentKeepalive = 25

Und Client 2 mit komplettem Traffic:

[Interface]
PrivateKey = < private Key des Clients >
Address = 192.168.20.20/32, fd00::20:20/128
# da der komplette Traffic durch die VPN-Verbindung geht, gilt dies auch für den DNS:
DNS = 192.168.20.1, fd00::20:1

[Peer]
PublicKey = < public Key des Servers >
PresharedKey = < private Key des PSK >
# hier der Unterschied für sämtlichen Traffic:
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.meinedomain.de:51820
PersistentKeepalive = 25

Die Freigabe in der Firewall sollte nicht vergessen werden. Aber ansonsten war es das schon. Erstaunlich einfach – wenn man denn dann die Parameter kennt.
Und das ganze DualStack!

Ein kleiner Nachtrag:

Man muss auf dem VPN-Server noch in der /etc/sysctl.conf diese zwei Einträge einkommentieren, damit der Traffic auch weitergeleitet wird:

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

Außerdem muss man ggf. den Traffic NATen. Mein IPv6-Netz im VPN ist ein privates. Ich habe mich dafür entschieden, weil das Prefix des öffentlichen Netzes sich jederzeit ändern kann und ich dann alle Konfigurationsdateien von Wireguard anpassen müsste. Um NAT zu aktivieren muss man folgende iptables rules anlegen (eth0 ist hier das normale Netzwerk-Interface – das kann ggf. anders heißen):

iptables -A FORWARD -i %i -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ip6tables -A FORWARD -i %i -j ACCEPT
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Wenn man anschließend noch das Paket iptables-persistent installiert kann man während der installation die vorhandenen rules bereits persistieren. Alternativ nach der Installation den vorhandenen iptables Status so sichern (diese 2 Dateien werden bei einem reboot automatisch geladen):

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