💾 Archived View for elfring.ms › blog › 2018-12-23_VPN-mit-Wireguard.gmi captured on 2022-03-01 at 15:09:31. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
In diesem Blog installiere ich ein VPN Gateway um den eigenen Internettraffic in öffentlichen W-LANs oder anderen potentiell unsicheren Netzen zu verschlüsseln und über einen eigenen Server in das Internet zu routen.
Wireguard ist eine moderne VPN Implementierung im Linux Kernel die mit einer relativ simplen Konfiguration auskommt. Die entsprechende Software wird auf dem Linux Server als dynamisches Kernelmodul installiert. Dabei besteht die Kernelimplementierung von Wireguard gerade einmal aus ca. 4000 Zeilen Code. Für die Clients gibt es entsprechende Pakete über den Packagemanager oder die Wireguard Homepage.
Die Begriffe Client und Server treffen es hier nicht wirklich da Wireguard praktisch "nur" virtuelle Netzwerkinterfaces bereitstellt die untereinander (verschlüsselt) verbunden sind. Der Server erhält seine Rolle dadurch, dass er eine Routinginstanz für den Internettraffic darstellt. Die mit * markierte Verbindung ist durch das VPN verschlüsselt.
VPN-Client VPN-Server ┌────────────────────┐ ┌───────────────────────┐ │ │ │ │ │ ┌──────────────┐ │ │ ┌──────────────┐ │ ┌─────────────────────┐ │ │ WG-Interface ├*********┼►│WG-Interface ├──────┼─►│ Internet Ressourcen │ │ └──────────────┘ │ │ └────────┬─────┴ │ └─────────────────────┘ │ ▲ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ ┌────────┴───────┐ │ │ ┌───────────────────┐ │ │ │ Browser & Apps │ │ │ │ Lokale Ressourcen │ │ │ └────────────────┘ │ │ └───────────────────┘ │ │ │ │ │ └────────────────────┘ └───────────────────────┘
Das Resultat ist also, dass der VPN CLient lediglich eine einzelne ausgehende verschlüsselte Verbindung zum VPN Server hat und damit auch in potentiell unsicheren Netzwerken nicht überwacht werden kann.
Im ersten Schritt wird die Software auf dem Arch Linux Server installiert. Da es sich um ein dynamisches Kernelmodul handelt, müssen auch die Linux-Header mitinstalliert werden.
$ sudo pacman -Sy linux-headers wireguard-tools wireguard-dkms
Schlüsselpaare
Als nächstes müssen die privaten und öffentlichen Schlüssel für Client und Server erzeugt werden. (Zur Verdeutlichung habe ich hier die Schlüsselrollen mit in die Keys geschrieben; tatsächlich werden nur die kryptischen Strings erzeugt.)
$ wg genkey 4EKnzma4x__SERVER-PRIV__EYvAnEBgPs8p3zAt81A= $ echo 4EKnzma4x__SERVER-PRIV__EYvAnEBgPs8p3zAt81A= | wg pubkey 31/uhemkNP__SERVER-PUB__n4unk8rHV3G5G/TX0m4= $ wg genkey yMvuuQou67g__CLIENT-PRIV__2/ruLh9Nb+gGZz/u0E= $ echo yMvuuQou67g__CLIENT-PRIV__2/ruLh9Nb+gGZz/u0E= | wg pubkey BT3mIYb93__CLIENT-PUB__Cg3FrnOsoeG2+7/aRCyg=
Konfiguration
Mit diesen Keys wird die Wireguard Konfiguration für den Server und den ersten Client erzeugt. Aus dem Namen der Konfigurationsdatei /etc/wireguard/wg0.conf leitet sich anschließend beim starten der Name des VPN Interfaces ab. Die Funktionen der einzelnen Parameter sind Inline komentiert. Die Konfiguration sollte nur für root lesbar sein, da der private Serverschlüssel hier hinterlegt ist.
## Die VPN-Serverkonfiguration: [Interface] # Die Serveradresse im VPN, hier wird auch das gesamte VPN als # Klasse C Netz definiert: Address = 10.1.1.1/24 # Der Listen Port des Servers: ListenPort = 51820 # Der private Schlüssel des Servers: PrivateKey = 4EKnzma4x__SERVER-PRIV__EYvAnEBgPs8p3zAt81A= # Skritpe die bei starten und stoppen des VPN ausgeführt werden # Hier wird die NAT für das Internetgateway eingerichtet und beim stoppen # wieder gelöscht. ens3 ist das Internet-Interface des Servers: PostUp = iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o ens3 \ -j MASQUERADE; \ iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED \ -j ACCEPT; \ iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT PostDown = iptables -t nat -D POSTROUTING -s 10.1.1.0/24 -o ens3 \ -j MASQUERADE; \ iptables -D FORWARD -m conntrack --ctstate RELATED,ESTABLISHED \ -j ACCEPT; \ iptables -D FORWARD -i wg0 -o ens3 -j ACCEPT ## Die Konfiguration für den ersten Client [Peer] # Der öffentliche schüssel des Clients: PublicKey = BT3mIYb93__CLIENT-PUB__Cg3FrnOsoeG2+7/aRCyg= # Die Adresse nutzt der Client innerhalb des VPN: AllowedIPs = 10.1.1.2/32
Da der Server als Internetgateway arbeiten soll muss das Forwarding von IP Verbindungen auf dem Server dauerhaft aktiviert werden. Dies erfolgt über einen Eintrag in /etc/sysctl.d/99-sysctl.conf. Dort gemachte Einstellungen werden bei jedem Serverstart geladen.
$ sudo sysctl net.ipv4.ip_forward=1 $ sudo sh -c 'echo net.ipv4.ip_forward=1 >> /etc/sysctl.d/99-sysctl.conf'
Das VPN starten
Das Kommando wg-quick liest diese Konfiguration und baut das VPN Interface auf dem Server auf.
$ sudo wg-quick up wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip address add 10.1.1.1/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o ens3 -j MASQUERADE; iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT; iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT
Das VPN Interface soll natürlich automatisch gestartet werden; das kann systemd übernehmen.
$ sudo systemctl enable wg-quick@wg0 Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /usr/lib/systemd/system/wg-quick@.service.
Der Android Client ist als Beta Version im Play Store verfügbar. Die Konfiguration selbst sieht dabei der Serverkonfiguration sehr ähnlich und kann über ein Textfile oder einen QR Code importiert werden. Alternativ stehen die Felder auch in der GUI zur Verfügung.
## Das VPN Interface auf dem Client: [Interface] Address = 10.1.1.2/32 PrivateKey = yMvuuQou67g__CLIENT-PRIV__2/ruLh9Nb+gGZz/u0E= # Ein öffentlicher DNS Server, da wir den aus dem lokalen Netz nicht nutzen DNS = 1.1.1.1 ## Dieses mal ist der "Peer" unser Server [Peer] PublicKey = 31/uhemkNP__SERVER-PUB__n4unk8rHV3G5G/TX0m4= # Die AllowedIPs sind hier die Adressen die in das VPN geroutet werden sollen, # ... also alle AllowedIPs = 0.0.0.0/0 Endpoint = vpnserver.example.com:51820
Damit kann das VPN auch auf dem Client gestartet werden. Um zu testen ob wir uns im Tunnel befinden, können wir zwei Tests machen: