In den letzten Blogposts habe ich gezeigt, wie ich mein privates VPN mit openVPN aufsetze. In diesem Post wiederhole ich das - nur eben mit Wireguard.
OpenVPN und Wireguard können auch problemlos nebeneinander laufen, wenn sie verschiedene Netzmasken benutzen. So hat man jeweils ein Fall-Back-Netz, mit dem man die Clients noch erreichen kann.
Auf dem Handy verbraucht openVPN mehr Strom, weil die Kryptosachen stärker sind. Wireguard ist da schlanker bei ausreichender Verschlüsselung.
VPN
Mein Wireguard-VPN soll unter den Netzen 10.3.3.0/24
und fd04:bab0:3::/64
laufen. Alle Clients sollen sich gegenseitig sehen und anpingen können. Auf Wunsch soll der gesamte Traffic über das VPN geroutet werden.
Installation
Unter Ubuntu lässt sich Wireguard auf Server und Clients wie folgt installieren:
#Ubuntu
apt install wireguard
#Arch, btw
pacman -S wireguard-tools
Schlüssel erzeugen
Auf meiner Zertifikationsinstanz (oder auf jedem anderen Rechner) erstelle ich mir einen neuen Ordner und erzeuge für den Server sowie für jeden Client ein Paar aus privatem und öffentlichem Schlüssel.
sudo bash
umask 077 && wg genkey | tee server-private.key | wg pubkey > server-public.key
umask 077 && wg genkey | tee client1-private.key | wg pubkey > client1-public.key
umask 077 && wg genkey | tee client2-private.key | wg pubkey > client2-public.key
umask 077 && wg genkey | tee client3-private.key | wg pubkey > client3-public.key
Die Inhalte der Schlüsseldateien werden gleich plaintext in die Configdateien geschrieben.
Server aufsetzen
Nach der Installation existiert das Verzeichnis /etc/wireguard
. In diesem Verzeichnis liegen die .conf
-Dateien der VPNs, egal ob Server oder Client. Der Name der .conf
-Datei entscheidet über den Namen der Interfaceschnittstelle. Benenne ich die Datei foobar.conf, so wird ein Tunneldevice mit dem Namen foobar
erzeugt. Die Datei tun0.conf
erzeugt ein Interface mit dem Namen tun0
. Standardmäßig (also in den Manuals im Netz) werden für Wireguard wg0
-Interfaces erzeugt.
Wir erzeugen also die Datei wg0.conf
und geben ihr folgenden Inhalt:
# ---------- Server Config ----------
[Interface]
## welche IP4-Adresse hat der Server im Tunnel?
Address = 10.3.3.1/24
## welche IPv6-Adresse hat der Server im Tunnel?
Address = fd04:bab0:3::1/64
# Wenn ihr iptables nutzt, dann wird hier das NAT zum Internet klargemacht
# Mein Device heisst eth0, eures auch? ansonsten ändern!
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.3.3.0/24 -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -s fd04:bab0:3::/64 -o eth0 -j MASQUERADE
# Sobald der VPN beendet wird, werden die iptables Regeln rückgängig gemacht
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.3.3.0/24 -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -s fd04:bab0:3::/64 -o eth0 -j MASQUERADE
# Hier kommt der private Key des Servers hin, in Plaintext
PrivateKey = OHUJätschibätschifasfdeg92wz4CvFqlWWUW74dfgM5+zPfuEU=
# Auf welchem Port soll der Server lauschen?
# Diesen Port in der Firewall freigeben!
ListenPort = 45881
## Für jeden Client kommt hier eine eigene Identifikation
[Peer] # Client1
# Schreibe hier den öffentlichen Schlüssel des Client1 hinein
PublicKey = AfuckAfDfejoqfooobaaarmHILbtoxReB6ZjzNuMtyYNxlM=
# Mit welchen IP4 und IPv6-Adressen soll sich der Client verbinden?
# Hier müssen ein /32 und /128 verwendet werden (= genau 1 IP-Adresse erlaubt)
AllowedIPs = 10.3.3.2/32, fd04:bab0:3::2/128
# Hier wiederholt sich das Ganze für Client2
[Peer] # CLient2
# Client public key
PublicKey = 1xejE9Z2OnkqkuckuckFcOsoLA623M1yRr+7/v7SmAtP36UmG8=
# IPs client can connect as (IPv4 /32 and IPv6 /128)
AllowedIPs = 10.3.3.3/32, fd04:bab0:3::3/128
[Peer] # Client3
# Client public key
PublicKey = sCid523sdfXwQHoErOyXyIk8UNEz36aff7+R9MIU8Xm4wc=
# IPs client can connect as (IPv4 /32 and IPv6 /128)
AllowedIPs = 10.3.3.4/32, fd04:bab0:3::4/128
- Der Server lauscht unter IP4 und IPv6 auf Port
45881
. Ihr könnt auch irgendeinen anderen Port auswählen. - Der Server wird unter den Adressen
10.3.3.1/24
undfd04:bab0:3::1/64
über den Tunnel ereichbar sein. Ebenso haben derzeit 3 Clients Zugriff, wobei jeder Client eine fixe IP4 und IPv6 im Tunnelnetz erhält. - Bei den
AllowedIPs
ist euch sicherlich aufgefallen, dass bei IP4 ein/32
und bei IPv6 ein/128
hinter die Adresse geschrieben werden muss.- Auf dem Server fungiert
AllowedIPs
ähnlich wie ein Router und gibt an, wohin der Datenverkehr geroutet werden soll. Daher genügt die Angabe von/32
oder eben/128
(genau eine IP-Adresse). - In der gleich folgenden Client-Config fungiert
AllowedIPs
wie eine Access-Controll-List. Daher muss in der Client-Config ein/24
bzw./64
definiert werden, um alles von10.3.3.*
bzw.fd04:bab0:3::
zu akzeptieren.
- Auf dem Server fungiert
- Soll ein weiterer Client hinzugefügt werden, muss in der Server-Config ein neuer [Peer]-Block mit dem puplic key des neuen Clients hinzugefügt werden.
Server starten
Ähnlich wie bei openVPN liest systemd das Verzeichnis /etc/wireguard
aus und macht alle dort befindlichen MY-VPN.conf
-Dateien verfügbar über den Service wg-quick@MY-VPN.service
.
Wir können unseren wg0
-Server starten mittels:
# Starten
systemctl start wg-quick@wg0.service
# Logs ansehen
journalctl -u wg-quick@wg0.service -f
Firewall anpassen
Falls ihr eine Firewall benutzt (und ich hoffe doch sehr, dass dies der Fall ist), muss diese für Wireguard angepasst werden. Einerseits muss der Server-Port freigegeben werden (ich habe da ja 45881
), anderseits müssen wir intern NAT
einrichten, wenn der Internetverkehr über den Tunnel geroutet werden soll.
iptables
Die iptables-Firewall muss auf dem Server und auf den Clients angepasst werden, damit openVPN funktioniert:
## Akzeptiere Pakete von den wg+ Interfaces
iptables -A INPUT -i wg+ -j ACCEPT
iptables -A FORWARD -i wg+ -j ACCEPT
## auf dem Server muss Port 45881 tcp/udp geöffnet werden
iptables -A INPUT -i eth0 -p tcp --dport 45881 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 45881 -j ACCEPT
Wenn euer Device nicht eth0
heisst, müsst ihr den Befehl entsprechend anpassen.
ufw
Die ufw-Firewall muss auf dem Server angepasst werden, damit Wireguard funktioniert. Zunächst muss der Serverport freigegeben werden:
sudo ufw allow 45881
Anschließend müssen drei weitere Dateien editiert werden, damit das Netz funktioniert.
/etc/default/ufw
nano /etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
2a. /etc/ufw/before.rules
, füge die folgenden Zeilen vor der *filter
-Sektion ein, um das NAT
für IPv4 zu aktivieren:
nano /etc/ufw/before.rules
# NAT-Tabelle hinzufügen
*nat
:POSTROUTING ACCEPT [0:0]
# OpenVPN-Regeln hinzufügen
-A POSTROUTING -s 10.3.3.0/24 -o eth0 -j MASQUERADE
COMMIT
2b. /etc/ufw/before6.rules
, 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:3::/64 -o eth0 -j MASQUERADE
COMMIT
Wenn euer Device nicht eth0
heisst, müsst ihr den Befehl entsprechend anpassen. Und falls ihr diese Einstellung gerade getroffen habt, könnt ihr in der wg0.conf
des Servers die Parameter PostUp
und PostUp
wieder auskommentieren.
/etc/ufw/sysctl.conf
nano /etc/ufw/sysctl.conf
net/ipv4/ip_forward=1
net/ipv6/conf/default/forwarding=1
net/ipv6/conf/all/forwarding=1
Client einrichten
Auf den Clients erzeugen wir ebenfalls die Datei /etc/wireguard/wg0.conf
und geben ihr diesen Inhalt:
# -------- Client Config ------------------
[Interface]
# IP4 Adresse des Clients, so wie in der Server-Config angegeben (/32!)
# Dieser Client bekommt 10.3.3.2
Address = 10.3.3.2/32
# IPv6 Adresse des Clients (use /128!)
# Dieser Client bekommt fd04:bab0:3::2
Address = fd04:bab0:3::2/128
# Der Private Key von Client1 im Plaintext
PrivateKey = GNJJAJT0MQnxRHga8Rzp/hLGoCtsefljhelahDks6EMD8Vw=
[Peer]
# Wie ist der Server erreichbar? Adresse und Port
#Endpoint = [2a02:08:15:4500:fckafd:4]:45881
#Endpoint = 192.168.0.1:45881
Endpoint = vpn.myserver.org:45881
# Der öffentliche Schlüssel des Servers im Plaintext
PublicKey = emV/wFCKAFD4WIyakB/JEi7jp9wH7zBCi81W+qjuMkWc=
# Sende alle x Sekunden einen Ping an das Netz
# um den Tunnel aufrecht zu erhalten.
# Sollte NIE auf dem Server gesetzt werden,
# sondern nur dort, wo auch "Endpoint" definiert ist.
# Also hier im Client...
PersistentKeepalive = 5
# Was soll durch den Tunnel geroutet werden?
## Option 1: nur Tunnelkrams durch den Tunnel routen
AllowedIPs = 10.3.3.0/24, fd04:3::/64
## Option 2: ALLES durch den Tunnel routen
#AllowedIPs = 0.0.0.0/0, ::/0
- Diese Datei muss ich nun bei jedem Client nach dem selben Muster anlegen.
- Der Client erhält seine fest IP4 und IPv6 über den Tunnel
- Dieses Mal müssen unter
Address
jeweils ein/32
bzw/128
vergeben werden (= 1 IP Adresse).- Der Parameter
AllowedIPs
fungiert im Clientmodus wie eine Access-Controll-List. Daher wird an dieser Stelle wieder ein/24
bzw./64
definiert, um alles von10.3.3.*
bzw.fd04:bab0:3::
über den Tunnel zu routen.
- Der Parameter
- Soll der gesamte Datenverkehr über den VPN-Tunnel geroutet werden, muss die zweite
AllowedIPs
-Zeile aktiviert (und die darüberstehende auskommentiert) werden.
Android
Für mein Handy erstelle mich mir wie oben beschrieben ein Schlüsselpaar und generiere mir eine Clientconfig wie oben, wobei ich die zweite AllowedIPs
-Option wähle (alles übers VPN routen). Diese wg0.conf
übertrage ich per KDE Connect auf mein Handy.
Als App installiere ich mittels F-Droid WG Tunnel von Zane Schepke, da die Original-Wireguard-App Ende 2023 aus dem F-Droid-Repository geflogen ist (weil sie einen integrierten Aktualisierer bekommen hat, der standardmäßig aktiviert ist und nicht transparent angibt, von wo aus er Aktualisierungen herunterlädt; noch fragt er um Zustimmung).
Jetzt kann ich einfach die übertragene wg0.conf
-Datei in der App importieren, und alles funktioniert bestens. Ok, in den App-Einstellungen musste ich noch “Tunnel on untrusted wifi” und “Tunnel on mobile data” aktivieren, dann hat es aber sofort funktioniert.
Weblinks
- https://www.wireguard.com/
- https://www.timoschindler.de/tag/arch-linux/
- https://github.com/zaneschepke/wgtunnel
- https://git.zilium.de/-/snippets/8
- https://android.stackexchange.com/questions/254262/why-isnt-wireguard-available-on-f-droid
- https://requestforcomments.de/archives/682