ubuntuusers.de

WireGuard

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


Du möchtest den Artikel für eine weitere Ubuntu-Version testen? Mitarbeit im Wiki ist immer willkommen! Dazu sind die Hinweise zum Testen von Artikeln zu beachten.

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.

Dieser Artikel behandelt die Grundlagen und legt den Schwerpunkt auf die Kommunikation zweier Rechner über WireGuard. Er ist Voraussetzung für die im Artikel WireGuard/Client-Server Architektur diskutierten Aspekte bei der Kommunikation mehrerer Rechner.

Installation

WireGuard ist ab Linux-Kernel Version 5.6 im Kernel enthalten und wurde auch in die Kernel der Ubuntu-LTS-Versionen Focal Fossa 20.04 (Kernel 5.4) und Bionic Beaver 18.04 (Kernel 4.15) zurück portiert.

Die Unterstützung für WireGuard kann über das folgende Paket aus den offiziellen Paketquellen von Ubuntu installiert werden [1]:

  • wireguard

Paketliste zum Kopieren:

sudo apt-get install wireguard 

Oder mit apturl installieren, Link: apt://wireguard

Dieses Paket prüft, ob der verwendete Kernel bereits ein eigenes Modul wirecard.ko enthält und installiert im anderen Fall das Paket wirecard-dkms, welches das benötigte Modul kompiliert. Außerdem werden auf jeden Fall die zur Einrichtung des VPN benötigten Werkzeuge installiert (Paket wirecard-tools).

Die Installation von wireguard-tools legt das Konfigurationsverzeichnis /etc/wireguard/ mit den zweckmäßigen Berechtigungen an. Kontrolle:

ls -ld /etc/wireguard/ 

mit der Ausgabe:

drwx------ 2 root root 4096 Okt 24 11:59 /etc/wireguard/

Das Konfigurationsverzeichnis muss die hier gezeigten Berechtigungen und Besitzer haben!

Eine Installation von WireGuard aus einer Fremdquelle ist ab August 2020 bei Ubuntu nicht mehr erforderlich.

Der Start des Moduls wireguard.ko erfolgt automatisch beim Erstellen einer WireGuard-Schnittstelle. Es kann optional auch bereits beim Start des Kernels automatisch durch ein Eintragen in der Datei /etc/modules geladen werden:

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 

Grundlagen

Die Teilnehmer eines WireGuard-VPNs kommunizieren über UDP/IP. Jeder Rechner in einem WireGuard-VPN muss daher alle Gegenstellen (Peers in der Nomenklatur von WireGuard) über dieses Protokoll erreichen können, dazu muss jeder Rechner die IP-Adresse und den von jeder Gegenstelle verwendeten UDP-Port kennen. Diese technischen Angaben benennt WireGuard als Endpoint. Die IP-Adresse einer Gegenstelle kann als numerische IPv4- bzw. IPv6-Adresse oder als DNS-Name angegeben werden, der DNS-Name muss aber für den jeweiligen Rechner zu einer gültigen IP-Adresse auflösbar sein.

Die zwischen den Teilnehmern eines WireGuard-VPNs per UDP/IP ausgetauschten Nachrichten werden immer asymmetrisch verschlüsselt. Es gibt also für jeden Teilnehmer einen privaten und einen öffentlichen (public) Schlüssel. Der private Schlüssel darf den Teilnehmer niemals verlassen und muss auf dem besitzenden Rechner vor unbefugtem Zugriff geschützt werden; üblicherweise ist er nur für den Benutzer root lesbar und wird in einem nur für root zugänglichen Verzeichnis (Standard: /etc/wireguard/) abgelegt. Wenn ein solcher privater Schüssel in fremde Hände gelangt, dann ist das WireGuard-VPN kompromittiert. Es ist daher ein Kunstfehler, wenn ein privater Schlüssel auf einem anderen Rechner erzeugt wird. Der zum privaten Schlüssel passende öffentliche Schlüssel muss dagegen an alle Teilnehmer im WireGuard-VPN verteilt werden.

Optional kann eine Gruppe von zwei oder mehr Teilnehmern (oder natürlich auch alle) in einem WireGuard-VPN zusätzlich eine weitere Verschlüsselungsschicht mit symmetrischer Verschlüsselung anwenden. Dazu muss für jede Gruppe ein gemeinsamer Schlüssel (preshared key) erzeugt und in der Gruppe (und nur in der Gruppe!) bekannt sein. Unterschiedliche Gruppen im VPN können unterschiedliche Geheimnisse verwenden. Dies ist als Vorsorge für den Fall gedacht, dass in Zukunft einmal jemand über ausreichende Berechnungskapazität verfügt, um aus dem öffentlichen Schlüssel eines Teilnehmers dessen privaten Schlüssel errechnen zu können. Diese Anleitung berücksichtigt diese optionale Zusatzverschlüsselung nicht weiter.

Jedem Teilnehmer im WireGuard-VPN muss mindestens eine interne IP-Adresse zugewiesen werden. Man kann auch mehrere Adressen oder Adressbereiche zuweisen. Die zugewiesenen Adressen müssen eineindeutig sein, man darf also weder eine Adresse mehreren Teilnehmern zuweisen noch Adressen verwenden, welche ein Teilnehmer außerhalb seines VPN erreichen kann. Jeder Teilnehmer eines WireGuard-VPN wird als Crypto-Router (so von WireGuard genannt) arbeiten und entschlüsselte Pakete an Rechner außerhalb des WireGuard-VPN weiterleiten.

Bei der Einrichtung eines WireGuard-VPNs hantiert man mit Informationen, die von anderen Rechnern stammen. Zur Verbesserung der Übersicht kann man optional den jeweiligen Hostname des originären Rechners in die Dateinamen aufnehmen. Die folgenden Anleitungen benutzen dafür die automatische Variable HOSTNAME der Shell bash. Bei Verwendung einer anderen Shell ist dies ggf. anzupassen.

Konfiguration

WireGuard enthält selbst keine Funktionalität zum Austausch der benötigten Schlüssel und Konfigurationsdaten zwischen den Teilnehmern, sondern dies muss außerhalb von WireGuard durch Zuruf oder besser Transfer von Konfigurationsdateien organisiert und durchgeführt werden. Beim Aufbau eines vollständig vermaschten Netzes (d.h. jeder sieht jeden direkt) aus N+1 Teilnehmern (N = 1, 2, …) werden (N+1) * N Austauschprozesse benötigt, also bei zwei Teilnehmern 2, bei drei Teilnehmern 6, bei vier Teilnehmern 12, bei fünf Teilnehmern 20 Austauschprozesse u.s.w. Der Aufwand wächst quadratisch und wird schnell unpraktikabel.

In dieser Anleitung wird daher als Netztopologie nicht das vollständig vermaschte Netz, sondern ein Sternnetz mit einem Mittelpunkt und N Außenstellen beschrieben. Jede Verbindung zwischen Mittelpunkt und einer Außenstelle wird als Peer-To-Peer-Netzwerk konfiguriert; damit beträgt der Aufwand für den Austausch der benötigten Konfigurationsdaten nur 2*N Austauschvorgänge. Das gesamte Netz ist also ein N-faches Peer-to-Peer-Netz. Zwei Außenstellen kommunizieren nicht direkt miteinander, sondern ausschließlich über den Mittelpunkt.

In dieser Anleitung wird jedoch zunächst nur die unmittelbare Kommunikation zwischen Außenstelle und Mittelpunkt konfiguriert. Für eine durch den Mittelpunkt vermittelte Kommunikation zwischen zwei Außenstellen siehe WireGuard/Client-Server Architektur.

Das folgende Bild zeigt ein WireGuard-VPN mit drei Rechnern Adele, Bobby und Corol, deren Netzwerk-Eigenschaften in dieser Anleitung beispielhaft verwendet werden.

WireGuard-VPN-im-Internet.png

Adele hat vom Internet-Provider den Adressbereich 2000:db8:1000::/64 (4 Gi Adressen) und die 16 Adressen in 192.0.2.128/28 zugewiesen bekommen und kann auch aus dem Internet über diese Adressen über die Schnittstelle Welt erreicht werden. Der Rechner verwendet für sich selber die beiden IP-Adressen 2000:db8:1000:: und 192.0.2.129. An der Schnittstelle LAN ist ein IPv4-Broadcast-Netz für maximal 13 weitere vollwertige Internet-Teilnehmer eingerichtet. Die beiden Adressen von Adele sind unter dem Namen adele.example.net im DNS oder DynDNS bekannt.

Bobby hat vom Internet-Provider den Adressbereich 2000:db8:c3d2::/64 und die 4 Adressen in 198.51.100.252/30 zugewiesen bekommen und kann auch aus dem Internet über diese Adressen über die Schnittstelle Welt erreicht werden. Der Rechner verwendet für sich selber die beiden IP-Adressen 2000:db8:c3d2:: und 198.51.100.255. An der Schnittstelle LAN ist ein IPv4-Point-to-Point-Netz für maximal 3 weitere vollwertige Internet-Teilnehmer eingerichtet.

Carol hat vom Internet-Provider den Adressbereich 2000:db8:abcd::/64, aber nur eine einzige IPv4 Adresse 203.0.113.99 zugewiesen bekommen. Bis auf die geänderten IPv6-Adressen unterscheidet sich Carol nicht von Bobby und kann auch aus dem Internet über diese IPv6-Adressen erreicht werden. Um nachgeschalteten Rechnern wenigstens eine eingeschränkte IPv4-Internet-Funktion zu ermöglichen, verwendet Carol einen vorgeschalteten NAT/PT-Router, welche die einzige öffentliche IPv4-Adresse auf den privaten Bereich 192.168.222.0/24 umsetzt. Carol verwendet für sich selbst die öffentliche Adresse 2000:db8:abcd:: und die private Adresse 192.168.222.22. Der vorgeschaltete Router ist für IPv6 transparent und beim Protokoll IPv4 muss für den Wireguard-UDP-Port von Carol eine Weiterleitung auf Carol eingerichtet werden.

Der Verwalter des WireGuard-Netzes hat für das gesamte Netz den Bereich fd00:5747:7767::/48 vorgesehen, daraus benutzt Adele die Adresse fd00:5747:7767:1000:/128 für sich, für Bobby ist der Bereich fd00:5747:7767:2000::/64 und für Carol der Bereich fd00:5747:7767:3000::/56 reserviert.

Vorbereitung

Der Rechner für den Mittelpunkt muss im Internet für anfragende Rechner erreichbar sein. Dazu muss mindestens eine der folgenden Voraussetzungen erfüllt sein:

  • Der Rechner besitzt eine dauerhaft zugeordnete öffentliche individuelle IPv4- oder IPv6-Adresse und befindet sich nicht hinter einem Router mit NAT: Die IP-Adresse des Rechners wird einmalig (als numerischer Wert oder DNS-Name) an alle weiteren Teilnehmer weitergegeben.

  • Der Rechner benutzt IPv4 und befindet sich hinter einem Router mit NAT:

    • Auf dem Router (nicht dem Rechner!) muss ein DDNS-Client die öffentliche IPv4-Adresse des Routers im DNS unter einem permanenten Namen veröffentlichen und laufend aktualisieren. An die weiteren Teilnehmer im WireGuard-Netz wird dieser permanente Name im DNS weitergegeben.

    • Zusätzlich: Auf dem Router muss für den UDP-Port des WireGuard-Rechners eine Port-Weiterleitung eingerichtet werden.

  • Der Rechner benutzt IPv6 und befindet sich hinter einem Router, welcher die zur Konfiguration erforderlichen Informationen bereit stellt. Er besitzt eine global geroutete individuelle IPv6-Adresse (aus dem Bereich 2000::/3), welche jedoch nicht dauerhaft diesem Rechner zugeordnet ist: Auf dem Rechner (nicht dem Router) muss ein DDNS-Client die öffentliche IPv6-Adresse des Rechners im DNS unter einem permanenten Namen veröffentlichen und laufend aktualisieren. An die weiteren Teilnehmer im WireGuard-Netz wird dieser permanente Name im DNS weiter gegeben.

Die Verwendung dynamischer DNS-Namen ist ein Notbehelf und mit den unter Problembehebung beschriebenen Einschränkungen behaftet.

Erstmalige Konfiguration

Auf jedem Teilnehmer sind drei Aufgaben durchzuführen:

  • A1: Erzeugung und IP-Konfiguration der Netzwerkschnittstelle und Erzeugung des privaten Schlüssels

  • A2: Export der öffentlichen Daten an andere Teilnehmer

  • A3: Import der öffentlichen Daten von einem anderen Teilnehmer, und dies ist für jeden Teilnehmer zu wiederholen

Diese Aufgaben müssen in einer bestimmten Reihenfolge erledigt werden:

  • Erster Schritt auf dem Mittelpunkt: A1, dann A2

  • Für jede Außenstelle:

    • zweiter Schritt auf der Außenstelle: A1, dann A2 und A3 (oder A3 und A2)

    • dritter Schritt auf dem Mittelpunkt: A3

Die folgenden drei Abschnitte beschreiben detailiert, wie man die benötigten Konfigurationsdateien systematisch mit den Dienstprogrammen von WireGuard erstellen kann. Einen möglicherweise schnelleren Weg findet man unter Alternative Konfiguration.

Schritt 1: Mittelpunkt, 1. Teil

In dieser Anleitung wird dieser Teilnehmer beispielhaft mit dem hostname Adele identifiziert.

  • Man wechselt zweckmäßigerweise in eine root-Shell, da man zum Ablegen der Schlüssel im Konfigurationsverzeichnis root-Rechte benötigt:

    sudo -i 
    1. Das benötigte WireGuard-Interface erschaffen:

      ip link add VPN type wireguard
      ip link set VPN up 

      Der Name der Schnittstelle (in dieser Anleitung beispielhaft: VPN) darf mit 1-15 Zeichen aus der Klasse [a-zA-Z0-9_=+.-] beliebig gewählt werden. Das Modul wireguard.ko wird durch den ersten Befehl automatisch geladen. Beim Einschalten (up) der Schnittstelle wird automatisch ein UDP-Port zugeordnet; man lässt sich diesen anzeigen und merkt sich den Wert für spätere Verwendung:

      wg show VPN listen-port 
    2. Zuordnung einer Adresse oder eines Adressbereiches: Man kann problemlos IPv6-Adressen benutzen. Wenn die durch WireGuard vertrauliche Kommunikation das VPN nicht verlassen soll, ist die Verwendung der lokal administrierten IP-Adressen aus dem Bereich fd00::/8 vorteilhaft. Wer die Kommunikation aus dem VPN ins offene Internet übergeben will, muss sich von seinem Internet-Provider IP-Adressen aus dem Bereich 2000::/3 zuweisen lassen und diese verwenden. Man kann natürlich auch die privaten IPv4-Adressen nach RFC1918 bzw. einem legal zugewiesene IPv4-Adressen verwenden.

      ip -6 addr add fd00:5747:7767:1000::/64 dev VPN 
    3. Erzeugung des privaten Schlüssel und und sichere Abspeicherung: WireGuard verwendet 256-Bit-Schlüssel. Man kann im Grunde jede beliebige Information von genau 32 Byte Länge verwenden. Für die Verwendung mit WireGuard muss man diesen Schlüssel als Base-64-Zeichenfolge kodieren. Dies ist nicht als Verschlüsselung gedacht, sondern dient nur zur druckbaren Darstellung des Schlüssels.

      • Die übliche Methode erzeugt einen zufälligen Schlüssel:

        umask 0077 ; wg genkey > /etc/wireguard/$HOSTNAME.secret 

        (Der umask-Befehl ist wesentlich!)

      • Alternative: Wenn man einen bestimmten Schlüssel verwenden möchte, kann man so vorgehen:

        #                           11111111112222222222233
        #                  12345678901234567890123456789012
        umask 0077 ; echo 'Adeles privater Schluessel!! xyz' | base64 - > /etc/wireguard/$HOSTNAME.secret 
    4. Das WireGuard-Interface mit diesem privaten Schlüssel konfigurieren:

      wg set VPN private-key /etc/wireguard/$HOSTNAME.secret 
    5. Permanente Konfigurationsdatei (welche später erweitert wird) anlegen:

      touch /etc/wireguard/VPN.conf ; wg-quick save VPN 

      Der Name einer Konfigurationsdatei für eine WireGuard-Schnittstelle muss den Namen der Schnittstelle mit dem Zusatz .conf lauten und im Konfigurationsverzeichnis /etc/wireguard/ liegen; im Beispiel enthält die Datei jetzt:

      [Interface]
      Address = fd00:5747:7767:1000::/64
      ListenPort = 48637
      PrivateKey = SEv8aWN1pqJ6HKyYR+80ZdfRtVGYbYvpe2EDaoOjaX4=

      In dieser Datei fehlen noch die bis jetzt unbekannten öffentlichen Daten der Gegenstellen, welche im Schritt 3 ergänzt werden.

  • Root-Shell beenden:

    exit 

Die im Verzeichnis /etc/wireguard/ erzeugten Dateien $HOSTNAME.secret bzw. Adele.secret und VPN.conf enthalten den privaten Schlüssel des Teilnehmers und dürfen nicht weitergegeben werden.

Dagegen müssen folgende Daten an alle anderen Teilnehmer verteilt werden:

  • der öffentliche Schlüssel:

    sudo wg show VPN public-key 
  • die öffentlich erreichbare IP-Adresse, am besten als FQDN

  • der UDP-Port, auf dem dieser WireGuard arbeitet:

    sudo wg show VPN listen-port 
  • die Adressen, für welche dieser Teilnehmer aus Sicht der anderen Teilnehmer zuständig sein soll.

Dazu kann man diese Informationen als normale Textdatei im WireGuard-Format (Name beispielhaft $HOSTNAME.peer) eines Peers aufbereiten:

[Peer]
# adele
PublicKey = Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY=
Endpoint = adele.example.net:48637
AllowedIPs = fd00:5747:7767:1000::/64

Diese Datei dient als Grundstock für die VPN.conf jeder Gegenstelle, muss aber noch auf jeder Gegenstelle individuell um deren private Daten ergänzt werden.

Man macht nun auf einem anderen Teilnehmer weiter.

Schritt 2: Außenpunkt

Dies ist innerhalb dieser Anleitung beispielhaft der hostname Bobby, oder auch Carol, David, Elise, …

  1. Die für den Mittelpunkt beschriebenen Schritt 1 führt man auch bei jedem weiteren Teilnehmer durch. Lediglich FQDN und die Adressbereiche sind anzupassen. In einer root-Shell sind dies die Befehle:

    ip link add VPN type wireguard
    ip link set VPN up
    ip -6 addr  add fd00:5747:7767:2000::/64 dev VPN   # individuell anpassen!
    umask 0077 ; wg genkey > /etc/wireguard/$HOSTNAME.secret 
    wg set VPN private-key /etc/wireguard/$HOSTNAME.secret 
    touch /etc/wireguard/VPN.conf ; wg-quick save VPN  

    Die Konfigurationsdatei für die Schnittstelle VPN von Bobby sieht nun so aus:

    [Interface]
    Address = fd00:5747:7767:2000::/64
    ListenPort = 41828
    PrivateKey = KPRaRgBEKgUQaNLKhjVVDNP5Pqf5CBDY3/FHWvDhwF4=
  2. Man beschafft sich die öffentliche Konfiguration des ersten Clients und importiert sie auf diesem Client als Peer:

    • Wenn man sie als Datei im WireGuard-Konfigurationsformat (Beispiel hier: /etc/wireguard/Adele.peer) vorliegen hat, geht das (immer noch in der root-Shell) einfach mit diesen Befehlen:

      wg-quick  up  VPN     # sofern die Schnittstelle nicht schon aus dem 1. Schritt noch aktiv ist
      wg addconf VPN /etc/wireguard/Adele.peer
      wq-quick save VPN 

      Bei diesem Schritt prüft wg die als Endpoint angegebenen DNS-Namen und ersetzt diese durch deren numerische Werte. Wenn dies zu diesem Zeitpunkt nicht möglich ist, erzeugt wg eine Fehlermeldung und die Übernahme der Daten des Teilnehmers misslingt.

    • Alternativ kann man die Konfiguration auch mit dem Programm wg in der root-Shell durchführen:

      #wg set VPN peer <base64-public-key> …
      wg set VPN peer Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY=   # PublicKey von Adele
      wg set VPN peer Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY endpoint adele.example.net:51499
      wg set VPN peer Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY= allowed-ips fd00:5747:7767:1000::/64
      wg set VPN peer Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY persistent-keepalive 25
      wq-quick save VPN 

      Man kann auch hinter dem öffentlichen Schlüssel mehrere Eigenschaften wie endpoint und allowed-ips hintereinander in einer Zeile angeben. Der Bezeichner allowed-ips darf mehrfach verwendet werden und man kann auch mehrere Adressbereiche durch Komma getrennt nacheinander angeben. Zur Option persistent-keepalive siehe Problembehebung.

  3. Die öffentliche Konfiguration dieses Teilnehmers, z.B. als aufbereitete Datei $HOSTNAME.peer bzw. Bobby.peer:

    [Peer]
    # bobby
    PublicKey = 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM=
    Endpoint = bobby.example.net:41828
    PersistentKeepalive = 25
    AllowedIPs = fd00:5747:7767:2000::/64

    überträgt man auf den Rechner im Mittelpunkt und macht auf diesem weiter.

Hinweis:

Die Schreibweise der Schlüsselworte wie z.B. "AllowedIPs" unterscheidet sich zwischen Konfigurationsdatei und Kommandozeile!

Beachte hier: Mit dieser Datei sagt die Außenstelle (z.B. Bobby), wie sie vom Mittelpunkt Adele aus gesehen werden will. Diese Datei ist nicht zur Verwendung auf der Außenstelle selbst gedacht.

Schritt 3: Mittelpunkt, 2. Teil

Man beschafft sich die öffentliche Konfiguration der Gegenstelle und importiert sie auf dem Rechner im Mittelpunkt als Peer.

  • Unter Verwendung einer peer-Datei, hier am Beispiel von Bobby:

    sudo wg-quick  up  VPN
    sudo wg addconf VPN Bobby.peer    # oder auch Carol, David, Elise und die ganze Sippschaft
    sudo wg-quick save VPN 
  • Alternativ durch manuelle Konfiguration mit dem Programm wg in der root-Shell:

    #wg set VPN peer <base64-public-key> …
    wg set VPN peer 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM=   # PublicKey von Bobby
    wg set VPN peer 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM= endpoint bobby.example.net:41828
    wg set VPN peer 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM= allowed-ips fd00:5747:7767:2000::/64
    wq-quick save VPN  

Für jeden weiteren Teilnehmer wiederholt man die Schritte 2 und 3.

Alternative Konfiguration

Nach Durchführung der drei Schritte hat man auf Adele und Bobby jeweils diese Konfigurationsdatei /etc/wireguard/VPN.conf:

Außenstelle Bobby Mittelpunkt Adele
[Interface]
Address = fd00:5747:7767:2000::/64
ListenPort = 41828
PrivateKey = KPRaRgBEKgUQaNLKhjVVDNP5Pqf5CBDY3/FHWvDhwF4=

[Peer]
PublicKey = Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY=
AllowedIPs = fd00:5747:7767:1000::/64
Endpoint = 192.0.2.129:48637
PersistentKeepalive = 25
[Interface]
Address = fd00:5747:7767:1000::/64
ListenPort = 48637
PrivateKey = SEv8aWN1pqJ6HKyYR+80ZdfRtVGYbYvpe2EDaoOjaX4=

[Peer]
PublicKey = 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM=
AllowedIPs = fd00:5747:7767:2000::/64
Endpoint = 198.51.100.255:41828
 

Die für jeden Teilnehmer benötigte individuelle Konfigurationsdatei /etc/wireguard/VPN.conf kann man alternativ natürlich auch einfach mit einem Texteditor anlegen. Die Datei muss root gehören und nur root darf sie lesen können. Den öffentlichen Schlüssel zu einem geheimen Schlüssel /etc/wireguard/Adele.secret kann man so ermitteln:

wg pubkey < /etc/wireguard/Adele.secret 

Teilnehmer löschen

So, wie ein Peer angelegt wird, kann er auch von einer aktiven WireGuard-Schnittstelle wieder gelöscht werden. In diesem Beispiel wird auf Adele der Peer Bobby entfernt:

sudo wg show all endpoints 

zeigt eine Liste der bekannten Gegenstellen an:

VPN	09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM=	198.51.100.255:41828

Man wählt die Schnittstelle (hier: VPN) und den öffentlichen Schlüssel des zu entfernenden Teilnehmers aus und entfernt diesen mit diesem Befehl:

sudo wg set VPN peer 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM= remove 

WireGuard verwenden

WireGuard kann, sobald man eine gültige Konfigurationsdatei besitzt, manuell über diese Befehle gestartet, gepflegt und auch wieder beendet werden:

sudo wg-quick up   VPN 

sudo wg-quick save VPN 

sudo wg-quick down VPN 

Hinweis:

Neben der eigentlichen Konfiguration von WireGuard inkl. der mit AllowedIPs definierten inneren Crypto-Routen muss natürlich auch die äußere IP-Konfiguration der Adressen und Routen stimmen. Das Programm wg-quick erledigt das durch Auswertung der Zeilen Address und AllowedIPs in der Konfigurationsdatei automatisch. Wenn man jedoch ohne dieses Programm arbeiten möchte, muss man diese Aufgabe selbst übernehmen. Die unten folgenden Beispiele für systemd-networkd und ifupdown berücksichtigen dies.

Den automatischen Start kann man einer systemd-Unit oder dem Netzwerk-Konfigurationsprogramm (bei Ubuntu versionsabhängig ìfupdown, NetworkManager oder systemd-networkd) übertragen.

Start per systemd-unit

Diese Methode funktioniert bei jeder Ubuntu-Version, welche systemd als Init-System verwendet.

Die Installation des Paketes wireguard-tools hat bereits den systemd-unit-Generator wg-quick@.service installiert. Damit kann man eine WireGuard-Schnittstelle VPN über systemd starten, untersuchen und stoppen:

systemctl start  wg-quick@VPN.service 

systemctl status wg-quick@VPN.service 

systemctl   stop wg-quick@VPN.service 

Für einen automatischen Start der WireGuard-Schnittstelle beim Hochfahren des Rechners sorgt:

systemctl enable wg-quick@VPN.service 

Den automatischen Start der WireGuard-Schnittstelle beim Hochfahren des Rechners unterbindet:

systemctl disable wg-quick@VPN.service 

Alle in diesem Abschnitt vorgestellten Befehle erfordern eine Konfigurationsdatei /etc/wireguard/VPN.conf, wie oben beschrieben.

Nach dem Start des Rechners sollte man sich vergewissern, dass die WireGuard-Schnittstelle nicht zusätzlich von einem weiteren Netzwerk-Konfigurationsprogramm, insbesondere nicht vom NetworkManager konfiguriert wird!

Start per NetworkManager

NetworkManager ab Version 1.16 kann mit WireGuard-Schnittstellen und -VPNs umgehen. Ubuntu 18.04 und früher enthalten keine ausreichend neue Version des NetworkManager, somit kann diese Methode nur ab Ubuntu 20.04 angewendet werden.

Die Unterstützung von WireGuard durch den NetworkManager ist jedoch zu Zeit (2020) noch unvollständig. Insbesondere unterstützen die GUI-Oberflächen WireGuard noch nicht. Mögliche oder bestehende WireGuard-Verbindungen werden in der GUI nicht angezeigt und lassen sich dort erst recht nicht bedienen und auch nicht per GUI anlegen, verwalten oder löschen.

Möglich sind diese Operationen:

  • Eine per wg-quick aufgebaute WireGuard-Verbindung wird auf der Kommandozeile angezeigt:

    nmcli devices
    nmcli connection 
  • Sie kann gestoppt werden:

    nmcli connection down VPN 

Man sollte dies vermeiden, denn eine so gestoppte Vebindung lässt sich nicht wieder per NetworkManager aufbauen und hinterlässt offenbar auch den Netzwerk-Stack in einem gestörten Zustand.

  • Eine Konfigurationsdatei im WireGuard-Format kann in NetworkManager importiert werden. NetworkManager legt dann für sich ein Verbindungsprofil vom Typ wireguard im Verzeichnis /etc/NetworkManager/system-connections/ an:

    sudo nmcli connection import  type wireguard file /etc/wireguard/VPN.conf 

Eine solches Verbindungsprofil wird auch vom NetworkManager sofort aktiviert, ebenso beim Hochlauf des Rechners wieder aktiviert. Das Verbindungsprofil kann von root wie üblich mit einen Texteditor bearbeitet werden.

  • Ein Verbindungsprofil des NetworkManager vom Typ wireguard kann auf der Kommandozeile mit diesen Befehlen angezeigt, gestartet und beendet werden:

    nmcli connection
    nmcli connection up VPN
    nmcli connection down VPN 

Start per systemd-networkd

Dies funktioniert bei allen Ubuntu-Versionen ab 18.04. Die Version von systemd bei Ubuntu 16.04 kennt die für WireGuard benötigten Schlüsselwort jedoch noch nicht.

Man muss als root im Verzeichnis /etc/systemd/network/ passende Konfigurationsdateien anlegen. Im wesentlichen ist eine Übersetzung der Syntax einer WireGuard-Konfigurationsdatei in das systemd-Format erforderlich. Das Prinzip wird an Beispielen verdeutlicht:

Auf jedem Rechner ist die Datei /etc/wireguard/VPN.conf in Dateien /etc/systemd/network/50-wireguard.netdev und /etc/systemd/network/50-wireguard.network umzuwandeln:

Außenstelle Bobby Mittelpunkt Adele
# /etc/systemd/network/50-wireguard.netdev
[NetDev]
Name = VPN
Kind = wireguard
Description = WireGuard Schnittstelle VPN

[WireGuard]
ListenPort = 41828
PrivateKey = KPRaRgBEKgUQaNLKhjVVDNP5Pqf5CBDY3/FHWvDhwF4=

[WireGuardPeer]
PublicKey = Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY=
AllowedIPs = fd00:5747:7767:1000::/64
Endpoint = 192.0.2.129:48637
#PersistentKeepalive = 25
und
# /etc/systemd/network/50-wireguard.network
[Match]
Name = VPN

[Network]
Address = fd00:5747:7767:2000::/64

[Route]
Destination =  fd00:5747:7767:1000::/64
# /etc/systemd/network/50-wireguard.netdev
[NetDev]
Name=VPN
Kind=wireguard
Description=WireGuard Schnittstelle VPN

[WireGuard]
ListenPort=48637
PrivateKey=SEv8aWN1pqJ6HKyYR+80ZdfRtVGYbYvpe2EDaoOjaX4=

[WireGuardPeer]
PublicKey=09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM=
AllowedIPs=fd00:5747:7767:2000::/64
Endpoint=198.51.100.255:41828
 
und
# /etc/systemd/network/50-wireguard.network
[Match]
Name=VPN

[Network]
Address=fd00:5747:7767:1000::/64

[Route]
Destination = fd00:5747:7767:2000::/64

Achtung!

Die Datei /etc/systemd/network/50-wireguard.netdev enthält den privaten Schlüssel und muss daher vor unbefugten Lesern geschützt werden. systemd-networkd liest seine Konfigurationsdateien als Systembenutzer systemd-network. Durch Anwendung von chmod und chown sollte man deshalb Rechte und Besitzer so setzen:

-rw-r----- 1 root systemd-network 0 Dez  1 08:29 /etc/systemd/network/50-wireguard.netdev

Nach der Umwandlung benötigt man die Datei /etc/wireguard/VPN.conf nicht mehr.

Zur Anwendung der Konfigurationsdateien muss systemd-networkd gestartet werden oder beim Hochlauf automatisch gestartet werden:

systemctl start systemd-networkd 

systemctl enable systemd-networkd 

Zur Deaktivierung des automatischen Starts der Schnittstelle entfernt man deren Konfigurationsdateien aus /etc/systemd/network/ oder man deaktiviert den automatischen Start von systemd-networkd.

Start per ifupdown

Diese Methode kann bei Ubuntu 16.04 angewendet werden. Bei späteren Ubuntu-Versionen muss das Paket ifupdown installiert werden und die Konfiguration des Netzwerks auf dieses Programm umgestellt werde.

Man missbraucht in der Datei /etc/network/interfaces die Schnittstelle lo zur Erzeugung einer WireGuard-Schnittstelle.

  • Man kann in der Konfiguration für die Schnittstelle VPN einfach wg-quick aufrufen, welches dann die Konfigurationsdatei /etc/wireguard/VPN.conf verwendet:

    iface lo inet loopback
      up          ip link add VPN type wireguard || true
    auto lo
    
    # WireGuard für Außenstelle Bobby
    iface VPN inet6 manual
      pre-up      ip link del $IFACE type wireguard || true
      up          wg-quick up   $IFACE
      down        wg-quick down $IFACE
      post-down   ip link add $IFACE type wireguard
    #auto VPN


    (Die Verwendung von del in der up-Sequenz und add in der down-Sequenz ist kein Schreibfehler! wg-quick erzeugt und vernichtet die Schnittstelle. Die bereits angelegte muss daher vor dem Hochfahren wieder gelöscht werden und nach dem Löschen beim Herunterfahren neu angelegt werden, damit man sie wieder starten kann.)

  • Alternativ kann man auch in der Datei /etc/network/interfaces selbst die Schnittstelle konfigurieren; dabei muss man die unter erstmaliger Konfiguration beschriebenen Befehle verwenden. Bei dieser Methode benötigt man keine Konfigurationsdatei für wg-quick im Verzeichnis /etc/wireguard/:

    iface lo inet loopback
      up          ip link add VPN type wireguard || true
    auto lo
    
    # WireGuard für Außenstelle Bobby
    iface VPN inet6 static
      PEER   Z/fkUwCqxYCzgEaOU/Y8X9a0je82oT7gKO86skxaaAY=
      address     fd00:5747:7767:2000::/64
      up          ip -6 route add fd00:5747:7767:1000::/64 dev $IFACE
      up          wg set $IFACE listen-port 35784
    # up          wg set $IFACE private-key /etc/wireguard/$HOSTNAME.secret   # funktioniert nicht, s.u.!
      up          wg set $IFACE private-key /etc/wireguard/SECRET
      up          wg set $IFACE peer $IF_PEER endpoint adele.example.net:51499
      up          wg set $IFACE peer $IF_PEER allowed-ips fd00:5747:7767:1000::/64
    #auto VPN

Als PEER gibt man den öffentlichen Schlüssel der Gegenstelle an. Man kann in /etc/network/interfaces den variablen Dateinamen $HOSTNAME.secret nicht verwenden, weil die Systemshell dash die Variable HOSTNAME nicht kennt.

Die WireGuard-Schnittstelle mit diesen Befehlen starten und stoppen:

sudo ifup   VPN 

sudo ifdown VPN 

Für den automatischen Start aktiviert man die Anweisung auto VPN.

Problembehebung

Installation

Wenn man einen Kernel verwendet, der selbst noch nicht über das Modul wireguard.ko verfügt, zieht die Installation des Paketes wireguard das Paket wireguard-dkms nach; dieses kompiliert das Modul aus dem Quelltext und installiert es als DKMS-Modul. Wenn es dabei zu Problemen kommt, konsultiere man den Wiki-Artikel über DKMS.

Keine Verbindung möglich

Wenn keine Verbindung eines Teilnehmers zum WireGuard-Netzwerk Clients zustande kommt, sollte man diese Punkte überprüfen:

  • Firewall auf allen beteiligten Rechnern: Die von WireGuard verwendeten UDP-Ports dürfen nicht gesperrt sein.

  • Portweiterleitung bei Verwendung von IPv4 als Transportmedium durch einen NAT-Router

  • IP-Adressen der Endpoints, bzw. Auflösung von DNS-Namen der Teilnehmer zu IP-Adressen, siehe auch: Probleme mit der dynamischen IP

Verbindungsabbrüche

Ein Teilnehmer hinter einer zustandsbehafteten Firewall (z.B. NAT/PT oder das Conntrack-Modul von Netfilter) kann die Verbindung verlieren, wenn die Firewall bei langen Pausen im Verkehr die UDP-Verbindung schließt. Als Gegenmaßnahme kann man bei solchen Teilnehmern den regelmäßigen Austausch leerer Pakete vorsehen. Man konfiguriert dies über die Option PersistentKeepalive mit Angabe einer Intervalldauer in Sekunden.

DNS-Namensauflösung gestört

wg-quick kennt noch weitere neben den hier beschriebenen Konfigurationsoptionen, wie z.B. "DNS = " zur Vorgabe von DNS-Servern. Diese Konfigurationsoption sollte man bei Ubuntu-Betriebssytemen vermeiden, da sonst die DNS-Namensauflösung gestört werden oder ausfallen kann.

WireGuard verwendet den Manager resolvconv zum Verwalten der Konfigurationen des DNS-Resolvers, Ubuntu jedoch ab Version 17.10 systemd-resolve für diese Aufgabe. Die beiden Programme stören sich gegenseitig.

Nach Neustart keine Verbindung möglich

Nach einem Neustart kann es passieren, dass die Schnittstelle nicht wie geplant angelegt bzw. konfiguriert wurde, weil beim Hochlauf des Rechners ein Fehler aufgetreten ist. Dies prüft man durch diese allgemeinen Befehle:

ip link show type wireguard
sudo wg show 

Wenn diese Befehle nichts oder nicht die erwartete Konfiguration ausgeben, lohnt oft ein Blick in das Systemlog, welches man nach dem Namen der Schnittstelle (hier: VPN) filtert:

journalctl -b | grep VPN 

Zur weiteren Fehlersuche sollte man den automatischen Start der Schnittstelle deaktivieren und den Rechner neu starten.

Probleme mit der dynamischen IP

Achtung!

Bei der Verwendung von DNS-Namen in den Konfigurationsdateien kann der automatische Start einer Netzwerk-Schnittstelle fehlschlagen, weil die Namensauflösung per Netzwerk noch nicht funktioniert. Dies führt zu minutenlangen Verzögerungen beim Hochlauf oder kann sogar den Hochlauf verhindern!

Abhilfen:

  • WireGuard-Schnittstellen nicht automatisch beim Hochlauf starten.

  • Für die DNS-Namensauflösung die Datei /etc/hosts verwenden. Dies hilft nicht bei dynamischen DNS-Namen.

  • Numerische IP-Angaben in den Konfigurationsdateien verwenden.

Auch wenn die DNS-Namensauflösung unterstützt wird, passiert dies nur beim Start der Schnittstelle. Wenn sich zur Laufzeit die IP eines Teilnehmers ändert, erkennt dies WireGuard automatisch und passt seine aktive Konfiguration an. Mit dem Befehl

wg-quick save VPN 

werden daher in der Konfigurationsdatei /etc/wireguard/VPN.conf alle DNS-Namen für die Gegenstellen mit deren aktuellen numerischen IP-Adressen überschrieben. Bei statischen IP-Adressen stellt dies kein Problem dar, bei der Verwendung temporärer IP-Adressen und dynamischen DNS-Namen verliert man damit aber die zur Wiederaufnahme der Verbindung benötigte Information zum Auffinden der Gegenstelle im Internet.

Um dieses Problem dauerhaft zu umgehen, benötigt man auf jedem WireGuard-Teilnehmer, welcher andere per DynDNS erreichen soll, eine Liste der Gegenstellen mit öffentlichen Schlüsseln und permanenten DynDNS-Namen.

Der Befehl (hier am Beispiel für Bobby)

sudo wg set VPN peer 09M4WRAtCtsHIWqu9eYEmVxP0HchAxtpxLgtJ94XhTM= endpoint bobby.example.net:41828

ersetzt in der Konfiguration der aktiven WireGuard-Schnittstelle VPN die veraltete IP-Adresse. WireGuard wird unverzüglich die gültige IP-Adresse per DNS-Abfrage ermitteln und verwenden.

Diese Technik kann man natürlich über ein Skript systematisieren und dieses manuell oder periodisch (z.B. per Crontab) ausführen.

wireguard-banner.jpg

Diese Revision wurde am 7. Mai 2021 09:09 von frustschieber erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Netzwerk, VPN, Peer-to-Peer, WireGuard, Sicherheit