WireGuard

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. Installation von Programmen

  2. Ein Terminal öffnen

  3. Einen Editor öffnen

  4. Rechte für Dateien und Ordner ändern

  5. Root-Rechte

  6. Iptables Regeln erstellen

Inhaltsverzeichnis
  1. Vorbereitung
  2. Installation
  3. Konfiguration
    1. Vorbereitung
    2. Einmalige Konfiguration
      1. Client 1
      2. Client 2
    3. Statische Konfiguration
      1. Client 1
      2. Client 2
      3. Überprüfen der Config
      4. Client 3 und mehr
      5. Client löschen
    4. LAN miteinbeziehen
      1. LAN per NAT
      2. LAN per IP Route
  4. Problembehebung
    1. Installation
    2. Keine Verbindung möglich
    3. Nach Neustart keine Verbindung möglich
    4. Probleme mit der dynamischen IP
    5. Fehler "Netzwerkschnittstelle nicht konf...
  5. Links

logo.png WireGuard 🇬🇧 ist eine Virtual-Private-Network-Software, welche als Alternative zu bekannten VPN-Lösungen wie OpenVPN und IPsec entwickelt wird. Es soll im Vergleich zu OpenVPN und IPsec einfacher zu konfigurieren sein sowie schneller und effizienter. WireGuard ist für unterschiedlichste Plattformen verfügbar. Im Gegensatz zu den anderen Lösungen basiert es nicht auf der Client-Server-Architektur, sondern auf der Peer-to-Peer-Architektur. Es kann aber auch die Client-Server Architektur simulieren, siehe WireGuard/Client-Server Architektur.

Vorbereitung

Aktuell ist Wireguard noch nicht im stabilen Kernel enthalten und muss deshalb als Modul über DKMS gebaut werden. Hierzu sind die Header-Pakete des Kernels notwendig.

Paketliste zum Kopieren:

sudo apt-get install linux-generic 

Oder mit apturl installieren, Link: apt://linux-generic

Installation

Da es sich hierbei noch um ein sehr junges Projekt handelt, sind die Pakete leider noch nicht in den offiziellen Paketquellen enthalten und müssen über eine Fremdquelle hinzugefügt werden. Dies sollte sich aber mit der nächsten LTS-Version von Ubuntu ändern.

Adresszeile zum Hinzufügen des PPAs:

Hinweis!

Zusätzliche Fremdquellen können das System gefährden.


Ein PPA unterstützt nicht zwangsläufig alle Ubuntu-Versionen. Weitere Informationen sind der Wiki/Vorlagen/PPA/ppa.png PPA-Beschreibung des Eigentümers/Teams wireguard zu entnehmen.

Damit Pakete aus dem PPA genutzt werden können, müssen die Paketquellen neu eingelesen werden.

Nach dem Aktualisieren der Paketquellen kann folgendes Paket installiert werden [1]:

Paketliste zum Kopieren:

sudo apt-get install wireguard-dkms wireguard-tools 

Oder mit apturl installieren, Link: apt://wireguard-dkms,wireguard-tools

Nach dem Kompilieren muss das Modul noch beim Booten geladen werden. Hierzu reicht ein Eintrag in der Datei /etc/modules.

echo "wireguard" | sudo tee -a /etc/modules 

Nach einem Neustart sollte das Modul geladen werden. Ohne Neustart kann das Modul auch manuell geladen werden:

sudo modprobe wireguard 

Konfiguration

Hier wird WireGuard als Peer-To-Peer-Netzwerk konfiguriert. Für eine Client-Server-Konfiguration siehe WireGuard/Client-Server Architektur.

Netzwerkübersicht-WireGuard.png

Vorbereitung

Wenn keiner der beiden Clients eine feste globale IP-Adresse hat, sollte man diese zuerst konfigurieren. Hierbei hilft das Erstellen einer Domain, welche mit der neuesten dynamischen Adresse verbunden ist. Erklärt wird dies in diesem Artikel DDNS-Clients

Einmalige Konfiguration

Client 1

Als erstes sollte man die erforderlichen Schlüssel im Verzeichnis /etc/wireguard generieren. [3][6]

cd /etc/wireguard
sudo wg genkey > private.key
sudo wg pubkey > public.key < private.key
sudo wg genpsk > psk.key 

Nun erstellt man die Schnittstelle mit einer Adresse, einem Namen und weist ihr einen Private Key zu.

sudo ip link add wg0 type wireguard
sudo ip addr add 192.168.3.1/24 dev wg0
sudo wg set wg0 private-key ./private.key 

Dann kann man die Schnittstelle starten.

sudo ip link set wg0 up 

Zur Überprüfung sollte man nun dieses Kommando ausführen:

sudo wg 

Hierbei sollte jetzt eine Ausgabe erscheinen, von der man sich den Listen Port merken sollte. Als letztes muss man dann noch Client 2 dem Client 1 bekannt machen, sodass er sich mit diesem verbinden könnte.

sudo wg set wg0 peer "Public Key von Client 2" preshared-key "Preshared Key File von Client 1 und 2" allowed-ips 192.168.3.2/32 endpoint beispiel2.domain.de:port 

Client 2

Das Gleiche sollte man nun auch bei Client 2 tun. Der "Preshared Key" muss nicht mehr neu erstellt werden, da er auf beiden Clients identisch sein muss. Deswegen sollte man ihn übertragen.

cd /etc/wireguard
sudo wg genkey > private.key
sudo wg pubkey > public.key < private.key 
sudo ip link add wg0 type wireguard
sudo ip addr add 192.168.3.2/24 dev wg0
sudo wg set wg0 private-key ./private.key
sudo ip link set wg0 up 
sudo wg 
sudo wg set wg0 peer "Public Key von Client 1" preshared-key "Preshared Key File von Client 1 und 2" allowed-ips 192.168.3.1/32 endpoint beispiel1.domain.de:port 

Statische Konfiguration

Achtung!

Wenn als IPs dynamische Adressen verwendet werden, muss man der Problembehandlung Probleme mit der dynamischen IP folgen.

Damit es nicht nur bei einer einmaligen Konfiguration bleibt, welche beim Neustart verloren geht, muss für jeden Client die Datei /etc/wireguard/wg0.conf erstellt werden.

Client 1

Die Datei /etc/wireguard/wg0.conf muss erstellt werden.

[Interface]
Address = 192.168.3.1/24
PrivateKey = Ausgabe von "sudo cat /etc/wireguard/private.key" von Client 1
ListenPort = 50002
SaveConfig = true

Weil in dieser Datei sicherheitskritische Schlüssel enthalten sind, sollte man auf jeden Fall die Rechte für die Datei einschränken. [5]

sudo chmod 0600 /etc/wireguard/wg0.conf 

wg0 als Service registrieren und starten:

sudo systemctl enable wg-quick@wg0.service
sudo systemctl daemon-reload
sudo systemctl start wg-quick@wg0 

Den Client 2 auf dem Client 1 hinzufügen:

sudo wg set wg0 peer "Public Key von Client 2" preshared-key "Preshared Key File von Client 1 und 2" allowed-ips 192.168.3.2/32 endpoint beispiel2.domain.de:port 

Client 2

Die Datei /etc/wireguard/wg0.conf muss erstellt werden.

[Interface]
Address = 192.168.3.2/24
PrivateKey = Ausgabe von "sudo cat /etc/wireguard/private.key" von Client 2 
ListenPort = 50002
SaveConfig = true

Auch die Rechte für diese Datei sollte man auf jeden Fall einschränken.

sudo chmod 0600 /etc/wireguard/wg0.conf 

wg0 als Service registrieren und starten:

sudo systemctl enable wg-quick@wg0.service
sudo systemctl daemon-reload
sudo systemctl start wg-quick@wg0 

Den Client 1 auf dem Client 2 hinzufügen:

sudo wg set wg0 peer "Public Key von Client 1" preshared-key "Preshared Key File von Client 1 und 2" allowed-ips 192.168.3.1/32 endpoint beispiel1.domain.de:port 

Überprüfen der Config

Mit folgendem Befehl kann überprüft werden, ob der Peer hinzugefügt wurde:

sudo wg  

Die Ausgabe müsste so aussehen:

  public key: Der Public Key des Client 2
  private key: (hidden)
  listening port: 50002


peer: Der Public Key des Client 1
  endpoint: 'Öffentliche IP Client 1':50002
  allowed ips: 192.168.3.1/32

Client 3 und mehr

Um noch mehr Clients hinzuzufügen, muss der Befehl nur angepasst für den Client 3 ausgeführt werden. Nachfolgend der Befehl auf Client 1.

sudo wg set wg0 peer "Public Key von Client 3" preshared-key "Preshared Key File von Client 1 und 3" allowed-ips 192.168.3.3/32 endpoint beispiel3.domain.de:port 

Client löschen

So, wie ein Peer angelegt wird, kann er auch wieder gelöscht werden.

sudo wg set wg0 peer 'der Public Key des Peer welcher entfernt werden soll' remove 

LAN miteinbeziehen

LAN per NAT

Um IP-Weiterleitung zu erlauben werden in der Datei /etc/sysctl.d/99-sysctl.conf die Auskommentierungen der Zeilen entfernt:

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

Auf dem Client, der den anderen Clients Zugriff auf das private Netzwerk gewähren soll, muss in der /etc/wireguard/wg0.conf nach [Interface] NAT eingeschaltet werden und die Absenderclient-IP auf die IP von eth0 mit MASQUERADE geändert werden:

PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE;  ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Bei den Clients, welche Zugriff haben sollen, müssen den Peers die IP-Adressen bzw. IP-Bereiche zugewiesen werden.

sudo wg set wg0 peer "Public Key von Client 1" allowed-ips 192.168.3.1/32 allowed-ips 192.168.1.0/24 
NAT nur für einzelen Ports

Wenn nur einzelne Ports weitergeleitet werden sollen, muss PostUp und PostDown erweitert werden.

Erneut wird NAT eingechaltet und die IP des Clients auf die IP von eth0 geändern.

iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE 

Es werden die TCP- und UDP-Ports, sowie in welchen Netzwerkbereich weitergeleitet werden soll, definiert. In diesem Beispiel der Port 22 für SSH

iptables -w-A FORWARD -i wg0 -p tcp --dport 22 -d 192.168.1.0/24 -j ACCEPT
iptables -w -A FORWARD -i wg0 -p udp --dport 22 -d 192.168.1.0/24 -j ACCEPT 

Zum Abschluss werden alle anderen Pakete verworfen.

iptables -w -A FORWARD -i wg0 -j DROP 

Dies muss in einer Zeile, getrennt mit Semikola, in /etc/wireguard/wg0.conf nach [Interface] eingetragen werden. Für IPv4 sieht dies so aus:

PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -w -A FORWARD -i wg0 -p tcp --dport 3389 -d 192.168.1.0/24 -j ACCEPT; 
iptables -w -A FORWARD -i wg0 -p udp --dport 3389 -d 192.168.1.0/24 -j ACCEPT; iptables -w -A FORWARD -i wg0 -j DROP
PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -w -D FORWARD -i wg0 -p tcp --dport 3389 -d 192.168.1.0/24 -j ACCEPT; 
iptables -w -D FORWARD -i wg0 -p udp --dport 3389 -d 192.168.1.0/24 -j ACCEPT; iptables -w -D FORWARD -i wg0 -j DROP

In vielen Fällen kann es hilfreich sein, den Ping weiterzuleiten. Dazu müssen die icmp-Pakete auch weitergeleitet werden.

iptables -w -A FORWARD -i wg0 -p icmp ACCEPT 

LAN per IP Route

Damit die Clients auch mit dem Netzwerk hinter den anderen Clients kommunizieren können, muss man bei allen Clients in der Datei /etc/network/interfaces Routen erstellen und bei allen Clients in der Datei /etc/wireguard/wg0.conf den Adressbereich des anderen Netzes hinzufügen.

Client 1

Die Datei /etc/network/interfaces muss mit diesem Inhalt angelegt werden. [7]

auto wg0
iface wg0 inet static
        address 192.168.3.1
        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
        post-up ip route add 192.168.2.0/24 via 192.168.3.1 dev wg0 #Diese Zeile ist für den Netzwerkzugriff zuständig
        down ip link delete wg0

Und auch in dieser Datei /etc/wireguard/wg0.conf muss nur eine Zeile eingefügt werden.

[Interface]
PrivateKey = Privat Key von Client 1 
ListenPort = 50002

[Peer]
PublicKey = Public Key von Client 2
PresharedKey = Preshared Key von Client 1 und 2
Endpoint = beispiel2.domain.de:50002
AllowedIPs = 192.168.3.2/32, 192.168.2.0/24 #Hier muss der Adressbereich des anderen Netzes hinzugefügt werden
Client 2

Dasselbe auch beim zweiten Client: in der Datei /etc/network/interfaces fügt man wieder dies ein:

auto wg0
iface wg0 inet static
        address 192.168.3.2
        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
        post-up ip route add 192.168.1.0/24 via 192.168.3.2 dev wg0 #Diese Zeile ist für den Netzwerkzugriff zuständig
        down ip link delete wg0

Und in die Datei /etc/wireguard/wg0.conf das:

[Interface]
PrivateKey = Privat Key von Client 2 
ListenPort = 50002

[Peer]
PublicKey = Public Key von Client 1
PresharedKey = Preshared Key von Client 1 und 2
Endpoint = beispiel1.domain.de:50002
AllowedIPs = 192.168.3.1/32, 192.168.1.0/24 #Hier muss wieder der Adressbereich des anderen Netzes hinzugefügt werden

Achtung!

Es darf kein Adressbereich in der Datei /etc/wireguard/wg0.conf zweimal vorhanden sein, ansonsten wird nur das erste Vorkommen beachtet und alle anderen nicht.

Problembehebung

Installation

Es kann bei der Installation zu Problemen kommen, sodass das Modul nicht ladbar ist. Die Ausgabe von modprobe wireguard ergibt dann: modprobe: FATAL: Module wireguard not found in directory /lib/modules/4.15.0-74-generic. Vermutlich fehlen dann die Kernel Headers; ggf. muss das Modul auch manuell gebaut werden.

sudo apt-get install linux-generic
sudo dkms status 

Der letzte Befehl zeigt die hinzugefügte Version des Wireguard-Moduls. Die Version kann mit dem nächsten Befehl manuell gebaut werden.

dkms build wireguard/0.0.20190406 

Keine Verbindung möglich

Wenn keine Verbindung zwischen beiden Clients zustande kommt, sollte man sowohl die Firewall als auch die Portweiterleitung überprüfen.

Nach Neustart keine Verbindung möglich

Nach einem Neustart kann es passieren, dass die Schnittstelle nicht wie geplant konfiguriert wurde. Das zeigt sich beim Ausführen des wg-Kommandos in folgender Form:

sudo wg 
interface: wg0

Die Netzwerkschnittstelle kann dann aber nicht mittels

sudo ifdown wg0 && sudo ifup wg0 

neu gestartet werden, sondern muss erst komplett entfernt und anschließend wieder gestartet werden.

sudo ip link delete wg0
sudo ifup wg0 

Probleme mit der dynamischen IP

Achtung!

Dynamische IPs können beim Systemstart nicht aufgelöst werden und deshalb kann sich das Booten um bis zu fünf Minuten verzögern, da das Konfigurieren von wg0 fehlschlägt. Dies kann durch das manuelle Starten von wg0 umgangen werden. Dafür muss in der Datei /etc/network/interfaces der automatische Start der Schnittstelle deaktiviert und dann der folgenden Anleitung gefolgt werden.

Bei dynamischer IP darf es kein aktives auto wg0 geben!

#auto wg0

Bei dynamischer IP muss wg0 manuell gestartet werden:

sudo ifup wg0 

Auch wenn die Domainauflösung dynamischer IP Adressen unterstützt wird, passiert dies nur beim Start der Schnittstelle. Wenn sich in der Laufzeit die IP eines Clients ändert, hilft nur ein Neustart der Schnittstelle:

sudo ifdown wg0 && sudo ifup wg0 

Um dieses Problem dauerhaft zu umgehen, hilft im Moment nur ein Cronjob in Kombination mit einem Skript für jeden Client, welcher sich mit diesem Client verbinden soll.

Um zu vermeiden, dass die Schnittstelle unnötig oft neu gestartet wird, erstellt man eine Datei mit diesem Inhalt, welches die Domain auflöst und überprüft, ob sich diese geändert hat. Hier sinnbildlich für "Client 1".

#!/bin/bash
# Status von der Schnittstelle überprüfen
wgstatus=$(wg)

if [ "$wgstatus" == "interface: wg0" ]
then
        ip link delete wg0 && ifup wg0
elif [ "$wgstatus" == "interface: wg0" ]
then
        ifup wg0
else
        file="/tmp/digIP.txt"

        digIP=$(dig +short beispiel2.domain.de) # Diese IP muss natürlich angepasst werden
        #echo "$digIP"

        if [ -e "$file" ]
        then
                fileTXT=$(cat "$file")
                if [ "$digIP" != "$fileTXT" ]
                then
                        #echo "Daten sind gleich"
                        /sbin/ifdown wg0
                        /sbin/ifup wg0
                        echo "$digIP" > "$file"
                fi
        else
                echo "$digIP" > "$file"
        fi
fi

Danach sollte man die Datei ausführbar machen:

sudo chmod +x "Pfad zum Skript" 

und in die Crontabelle trägt man zum Beispiel Folgendes ein:

#sudo crontab -e # Aufruf der Crontabelle für Befehle mit root-Zugriff
*/10 * * * * "Pfad zum Skript" # Führt das Skript alle 10 Minuten aus

Fehler "Netzwerkschnittstelle nicht konfiguriert" beim Befehl ifdown wg0

Wenn dieser Fehler auftritt, hilft das manuelle Löschen der Schnittstelle:

sudo ip link delete wg0 

wireguard-banner.jpg