Wireguard

Ich betreibe Wireguard auf gehosteten Servern im Internet und verbinde Clients aus dem lokalen Netz damit, um z.B. auch Dienste, die ich lokal hoste, aus dem Internet heraus nutzen zu können. Mit dieser Lösung brauche ich meine lokalen Systeme nicht über Port-Forwarding und dynamisches DNS ins Internet zu exponieren.



Installation und Konfiguration auf dem Server

Auf dem Server im Internet richte ich den VPN-Knoten ein, der quasi die Zentrale bilden soll. Ich bezeichne das als VPN-Hub. Ich richte meine Hub auf einem Debian-Server ein, den ich natürlich vorher angemessen abgesichert habe. In den Distributionen Debian und Ubuntu ist wireguard in den Paketquellen enthalten. Es kann daher einfach mit


sudo apt install wireguard
            
installiert werden. Damit das Routing innerhalb der VPN-Tunnel funktioniert, muss in der Datei /etc/sysctl.conf ein Eintrag

net.ipv4.ip_forward=1
            
vorhanden sein. Ich muss also entweder eine neue Datei mit diesem Inhalt erstellen oder ggf. in einer bereits vorhandenen Datei dieses Namens eine Raute vor diesem Eintrag entfernen. Dann muss ich mit

sudo sysctl -p
            
diese Einstellung aktivieren. Spätestens jetzt wechsele ich mit

sudo su
            
zunächst in den Root-Modus um nicht immer wieder "sudo" schreiben zu müssen. Ich wechsele mit

cd /etc/wireguard
            
in den Ordner mit den Wireguard-Konfigurationen. Hier angekommen erstelle ich ein Paar aus privatem und öffentlichem Schlüssel, lasse sie mir beide auf der Konsole anzeigen, weil ich sie gleich brauche und ändere die Berechtigungen für den privaten Schlüssel so, dass nur der Besitzer ihn nutzen darf:

umask 077; wg genkey | tee privatekey | wg pubkey > publickey
cat privatekey
cat publickey
chmod 600 /etc/wireguard/privatekey 
            
Zunächst richte ich den VPN-Server ein, mit dem sich Clients dann verbinden können. Dazu erstelle ich mit dem Editor nano die Datei wg0 in diesem Verzeichnis /etc/wireguard mit folgendem Inhalt:

[Interface]
Address = 100.100.100.1/32
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
ListenPort = 51820
PrivateKey = Private Key des Servers (s.o.)
            
Dieses Tutorial beschränkt sich auf IPv4. Grundsätzlich funktioniert das auch mit IPv6 oder im Dual-Stack-Modus. Ich möchte also für meinen VPN-Tunnel das Subnetz 100.100.100.0/24 nutzen und mein Hub bekommt die VPN-Adresse 100.100.100.1. Die Netzwerkkarte meines virtuellen Servers hat die Bezeichnung "ens18". Die Bezeichnung muss ggf. angepasst werden. Wie die Karte heißt, kann ich mit "ip a" herausfinden.

Den Tunnel aktivieren ich mit

wg-quick up wg0
           
und mit

systemctl enable wg-quick@wg0
           
sorge ich dafür, dass der Tunnel beim Neustart des Servers wieder mit hochkommt.



Installation und Konfiguration der (Linux-)Clients

Ich behandele hier nur die Einrichtung des VPN-Tunnels auf Linux-Clients, weil das mein vorgesehener Einsatzzweck ist. Zunächst installiere ich Wireguard ebenso wie auf dem Server und richte die Datei /etc/sysctl.conf ein (s.o.). Ebenso erstelle ich das Schlüsselpaar in dem Ordner /etc/wireguard und ändere die Berechtigung des privaten Schlüssels. Die Datei /etc/wireguard/wg0.conf sieht bei den Clients wie folgt aus:


[Interface] 
PrivateKey = [Privater Schlüssel des Clients]
Address = 100.100.100.2/32

[Peer] 
PublicKey = [Öffentlicher Schlüssel des Hub]
Endpoint = [Öffentliche IP-Adresse des Hub]:51820
AllowedIPs = 100.100.100.0/24
PersistentKeepalive = 25
            
Die Angaben sind weitestgehend selbst erklärend. Auch auf den Clients starte ich den Wireguard-Tunnel mit

wg-quick up wg0
           
und mit

systemctl enable wg-quick@wg0
           
kann ich - wenn ich das möchte - festlegen, dass auch auf dem Client der Tunnel immer beim Starten mit gestartet wird. Noch funktioniert die Verbindung aber nicht. Der Hub muss den Client zunächst akzeptieren. Dafür kenne ich zwei Methoden.

Methode 1 ist, auf der Console des Hub folgenden Befehl abzusetzen:

wg set wg0 peer <öffentlicher Schlüssel des CLIENTEN> allowed-ips 100.100.100.2/32
           
Methode 2 besteht darin, in der Datei /etc/wireguard/wg0.conf des Hub manuell Einträge zu pflegen. Diese Methode bevorzuge ich, weil ich die Peers (also Clients) so besser pflegen und dokumentieren kann. Ich ergänze diese Datei um Einträge wie

#-------------------------------------------------------------
# Peer smb
[Peer]
PublicKey = [Öffentlicher Schlüssel des Clients]
AllowedIps = 100.100.100.2/32
           
Nachdem ich einen Peer mit der einen oder anderen Methode hinzugefügt habe, muss der Hub die Konfiguration aktualisieren. Dazu setze ich auf diesem Hub den Befehl

wg syncconf wg0 <(wg-quick strip wg0)
           
ab, während ich mich natürlich immer noch mit Rootrechten im Verzeichnis /etc/wireguard herumtreibe.



Funktionstest

Nun sollte die Verbindung zwischen dem Client und dem Hub bestehen. Ich kann das testen, indem ich vom Client aus den Server und/oder vom Server aus den Client anpinge.


# vom Client aus:
ping 100.100.100.1

# vom Server aus:
ping 100.100.100.2
           
Beides sollte nun funktionieren. Wenn das nicht klappt, dann liegt das sehr häufig an einer Vertauschung von privaten und öffentlichen Schlüsseln. Ich muss also genau prüfen, welche Schlüssel ich in die beiden Dateien wg0.conf eingetragen habe. Natürlich muss auf beiden Systemen die Firewall die Nutzung des Ports 51820 zulassen.