Wireguard auf dem Raspberry Pi

(Dieser Beitrag wurda am 25. Januar 2021 aktualisiert.)

Wireguard auf einem Raspi


<<< Installation Pi-hole auf Raspberry Pi <<< | >>> Installation Wireguard auf Ubuntu Server LTS 20.04 >>>


Der Raspberry ist natürlich perfekt als Wireguard Tunnel Device geeignet. Ich muss also nicht am PC oder Notebook einen Client starten, wenn der Raspi diese Funktion für das gesamte Netz übernehmen kann. Wer den Raspi bereits wie hier beschrieben installiert und vielleicht sogar schon Pi-hole, als DNS Server, so wie in meinem zweiten Beitrag konfiguriert hat, kann eigentlich direkt loslegen.

Quelle der Anleitung ist die offizielle Empfehlung auf der Seite von raspberrypi.org. Dieser Beitrag wurde geschrieben, als diese Anleitung den Stand 13.06.2020 hatte und übergreifend für Raspberries von Pi0 bis Pi4 galt. Dieser folge ich hier Step by Step. Die Konfiguration von Wireguard auf dem Raspi passe ich dann meinen Anforderungen und Gegebenheiten an.

Raspberry OS, hier auf Debian Buster 10 und dem Linux Kernel 5.4.83-v7+ #1379 basierend, hat leider noch keine native Wireguard Integration und auch noch keine Repositories hierfür offiziell released. Dies ist erst ab der Linux Kernel Version 5.6 der Fall (bspw. Ubuntu LTS 20.04). Dieser ist für das Raspberry OS noch nicht released (Stand 24.01.2021). Deshalb muss ein kleiner Umweg über das sog. Backport Repository von Wireguard gegangen werden. Sollte sich das künftig ändern, werde ich den Beitrag bei Gelegenheit aktualisieren, aber bis dahin behält er seine Gültigkeit.

Hier die Kurzfassung für Fortgeschrittene:

  1. Raspi aktualisieren
  2. Kernel Headers installieren
  3. Backport Repository einbinden
  4. Wireguard installieren</>
  5. Wireguard konfigurieren
  6. Routing (via IP Tables) einrichten

Für alle die, welche zwar auf der Shell klarkommen, aber die Kurzanleitung nicht ausreicht, geht’s hier weiter…

Wireguard Installation

  1. Zuerst – wie gewohnt – den Raspi aktualisieren mit
    sudo apt update

    und

    sudo apt full-upgrade -y
  2. Jetzt gilt es die Kernel-Headers zu installieren, damit der Raspi überhaupt etwas mit den Wireguard Paketen anfangen und ggfs. Abhängigkeiten auflösen kann. Das könnte etwas dauern, also nur nicht ungeduldig werden! Also starten wir die Installation mit
    sudo apt install raspberrypi-kernel-headers libelf-dev libmnl-dev build-essential git -y

  3. Jetzt gilt es die Installationsquellen auf den Raspi zu kopieren, zuerst Wireguard an sich…
    sudo git clone https://git.zx2c4.com/wireguard-linux-compat

    … dann die Wireguard Tools zur Verwaltung

    sudo git clone https://git.zx2c4.com/wireguard-tools

  4. Da wir jetzt im Prinzip nur die Sources, aber noch kein lauffähiges "Installationsprogramm" haben, muss dies unter Unix Derivaten zunächst erstellt (kompiliert) werden. Unter Unix wird hierfür der C Compiler verwendet. Diese Zeile kompiliert die Source Files für Wireguard und stellt dem System das Modul für die Installation bereit:
    sudo make -C wireguard-linux-compat/src -j$(nproc)


    Nachdem das Modul Wireguard nun kompiliert wurde, müssen wir es installieren. Das tun wir mit

    sudo make -C wireguard-linux-compat/src install

  5. Den auftretenden Fehler ignorieren wir, er hängt mit der Kernel Version und den installierten Kernel-Headers zusammen. Hat aber keinen Einfluss auf die Funktion von Wireguard.

  6. Beide Schritte wiederholen wir jetzt für die Wireguard Tools…
    sudo make -C wireguard-tools/src -j$(nproc)

    sudo make -C wireguard-tools/src install

  7. Im nächsten Step aktivieren wir das IP Forwarding auf dem Raspi. Diese Funktion wird uns später das Routing über den Raspi an die Zielnetze ermöglichen.
    Danach erfolgt direkt ein Reboot.

    sudo perl -pi -e 's/#{1,}?net.ipv4.ip_forward ?= ?(0|1)/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
    sudo reboot


    Nach dem Reboot prüfen wir, ob das IP Forwarding tatsächlich aktiviert wurde. Das Ergebnis ist korrekt, wenn die entsprechende Zeile, aus der Konfiguration wie im Screenshot zurückgegeben wird.

    sysctl net.ipv4.ip_forward

Damit ist der erste Teil der Aufgabe erledigt, Wireguard und die Management Tools sind installiert! Ab jetzt geht es an die Konfiguration von Wireguard.

Wireguard Konfiguration

Damit man die Konfiguration und vor allem die erforderliche Konfiguration der anderen lokalen Netzwerk-Geräte versteht, muss man zunächst Wireguard verstehen.
Ein Wireguard Tunnel verfolgt einen komplett anderen Ansatz, als bisher bekannte Tunnel Anwendungen wie IPSEC, OpenVPn etc… Wireguard verschlüsselt den Traffic, zwischen zwei sog. Peers asymmetrisch, also mit einem privaten und einem öffentlichen Schlüssel. Diese Peers sind vergleichbar mit den IPSEC Gateways oder OpenSSL Servern der anderen beiden Lösungen. Der private Schlüssel eines Peers ist besonders zu schützen und niemandem preiszugeben. Der öffentliche Schlüssel hingegen "identifiziert einen Peer bei seinem Peering-Partner und vice versa, wenn der Tunnel aufegbaut werden soll. vergleichbar mit einem Zertifikat, für eine Authentifizierung. Als Transportprotokoll verwendet Wireguard ausschließlich UDP. Die verwendete Schnittstelle wurde bereits mit der Installation von Wireguard angelegt und heißt standardmäßig wg0. Nachdem die beiden Schlüssel erfolgreich ausgetauscht wurden, ist es die Konfiguration, welche die Zugriffe, das Routing und andere Parameter festlegt. Alles in EINEM File, wenn nötig. Möchte man bei vielen Peers die Übersicht wahren, können die Konfigurationsdateien auch pro Peer angelegt und verwendet werden.

  1. Legen wir also mit dem erstellen der notwendigen Schlüssel los. Wir tun das, indem wir zuerst die Identität zu su wechseln und anschließend unter dieser Identität alle weiteren Schritte durchführen…
    sudo su

    Jetzt ins Wireguard Verzeichnis wechseln:

    cd /etc/wireguard

    Jetzt legen wir fest, dass niemand außer su die Dateien in diesem Verzeichnis ändern oder auch nur lesen darf:

    umask 077

    Das Schlüsselpaar erstellen (schon das geschieht mit der Anwendung Wireguard, also kein OpenSSL o.ä.). Schlüsselpaar deshalb, weil beide Schlüssel in Abhängigkeit zueinander "verschlüsselt" und auf der Gegenseite mit dem selben Verfahren wieder "entschlüsselt" werden. Hierzu wird beim Connect eine Random Number und der Public Key quasi gesendet und der Empfänger kann diese Information mit seinem privaten Schlüssel dechiffrieren. Mit dem folgenden Befehl wird also das Schlüsselpaar erstellt UND der private Schlüssel an das Interface wg0 gebunden.

    wg genkey | tee private.key | wg pubkey > public.key

    jetzt prüfen wir, ob beide Keys erstellt und gespeichert wurden, mit einem einfachen

    ls

    Falls erfolgreich, sollte das Ergebnis so aussehen…

    Jetzt beide Schlüssel anzeigen und schonmal sicher abspeichern! Achte auf ungewollte Leerzeichen beim Kopieren!

    cat public.key
    cat private.key

    Alles in Allem sehen die bisher beschriebenen Schritte, in der Shell dann so aus:

  2. Kommen wir nun zum wichtigsten Teil, der Wireguard Konfigurationsdatei. In dieser Datei werden nahezu alle Einstellungen, bei allen Peers vorgenommen, vergleichbar mit der Konfiguration einer traditionellen VPN Client Software.Vorab machen wir uns aber Gedanken über unser künftiges Netzwerk-Design. Wireguard sollte hierbei in einem komplett eigenen Netzwerksegment laufen und darf sich nicht mit dem bestehenden Heimnetz überlappen. Insofern schlage ich vor, man verwendet ein als "privates" Netzwerk definiertes Netz-Segment. Dazu gehören genau diese Supernetze:
    • 192.168.0.0/16 –> Sicher bekannt, da viele Heimrouter das Subnetz 192.168.0.0/24 oder auch 192.168.1.0/24 verwenden, welche Subnetze dieses Supernets sind.
    • 172.16.0.0/12 –> Weniger bekannt, da dieses Segment kaum bei Heimnatzen verwendet wird, es sei denn, der Heim-Admin verwendet speziell dieses Netz. Übrigens, entegegen vieler anderer Integrationen die ich schon gesehen habe, lautet die CIDR Notation tatsächlich /12 nicht /16!
    • 10.0.0.0/8 –> Im Regelfall kommt dieses Segment bei Unternehmen und großen Netz-Implementierungen zum Einsatz

    Beim Design muss man natürlich beide Seiten des Wireguard Tunnels (in diesem Beitrag geht ja eigentlich erstmal nur um den Client) betrachten.
    Insofern sieht mein Netz-Konstrukt, vollständig betrachtet wie folgt aus:

    Ich habe mich für das Subnetz 172.20.20.0/24 entschieden und werde mein Design auf diesem Netz aufbauen.
    Wer ein anderes Subnet verwenden möchte, kann die entsprechenden Einstellungen anpassen und übernehmen.

    Zusätzlich muss man noch einen UDP Port für die Kommunikation festlegen. Wireguard benötigt auf beiden Seite einen entsprechend identisch konfigurierten UDP Port, welcher frei definierbar ist, aber natürlich auch freigeschaltet sein muss. (Hotel Hotspots, Flughafen Hotspots, etc. öffnen im Regelfall lediglich TCP 80 (HTTP), TCP 443 (HTTPS) und selten auch UDP 53 (DNS). Diese Ports können aber NICHT für Wireguard verwendet werden. Wer jetzt doch die Idee hat, UDP 53 (DNS) hierfür zu verwenden, wird scheitern, denn Wireguard verhindert "by Design" den Start der Wireguard Schnittstelle wg0 auf diesem Port, da hier im Regelfall bereits "resolved/dnscrypt-proxy" horcht. Nachzulesen ist dieses Problem auch hier.
    Ich habe mich im Bespiel für den Port UDP 51238 entschieden.

    Die Wireguard Konfigurationsdatei wird jetzt einfach mit folgendem Befehl erstellt und direkt im geöffenten Editor bearbeitet:

    sudo nano /etc/wireguard/wg0.conf

    Es öffnet sich eine leere Konfigurationsdatei, also befüllen wir diese jetzt mit den Konfgurationswerten Werten. Die Datei ist entsprechend strukturiert und akzeptiert nur die unten genannten Werte und Parameter. Aufpassen, Leerzeichen gehören genau da hin, wo sie sich befinden. Also einfach die Vorlage reinkopieren und bei Bedarf entsprechend anpassen.

    [Interface]
    Address = 172.20.20.11/24
    ListenPort = 51238
    DNS = 10.1.110.1
    PrivateKey = Private_Key_des_Raspi_Peers
    
    PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
    
    # Wireguard Server
    [Peer]
    PublicKey = Public_Key_des_Wireguard Servers
    AllowedIPs = 172.20.20.1/32
    PersistentkeepAlive = 60
    

    Kurz zur Beschreibung der Parameter:

    • [Interface] –> Hiermit beginnt die Interface Konfiguration des lokalen Clients
    • Address –> Die lokale Wireguard Adresse, wie oben beschrieben…
    • PrivateKey –> Der an das Interface gebundene Private Key zum Dechiffrieren des Traffic
    • ListenPort –> Oben genannter UDP Port für die kommunikation der Peers
    • DNS –> Man kann hier einen DNS Server angeben, der zur Auflösung der DNS Namen verwendet wird, wenn DNS Anfragen an das Zielnetz geschickt werden
    • PostUp… –> Diese Zeile aktiviert NAT (Network Address Translation) via IPTables am lokalen System, sobald das Wireguard Interface aktiviert wird. Damit kann man den Traffic auf der Zielseite an das gesamte Zielnetz routen. Ob das geht, ist direkt abhängig von den Einstellungen "Allowed IPs" weiter unten!
    • PostDown… –> Diese Zeile deaktiviert NAT bei Shutdown des Interfaces wieder
    • [Peer] –> Beginn der Einstellungen des Peers
    • Endpoint –> Das öffentliche Gateway, also ein öffentlicher Name oder eine öffentliche IP des Peers.
    • PublicKey –> Der öffentliche Schlüssel des Peer. Nur wenn dieser bekannt ist, wird die VPN Session überhaupt gestartet.
    • AllowedIPs –> Im Prinzip eine ACl, die clientseitig steuert, für welche Zielnetze Pakete durch den Wireguard Tunnel geschickt werden sollen (Split Tunnel). Möchte man nach Aktivieren der Schnittstelle ALLE Pakete durch den Tunnel routen, käme hier 0.0.0.0/0, ::/0 rein (Full Tunnel).
    • PersistentKeepalive –> Ein Keep Alive, der die Session aufrecht erhält
    • Auskommentiert wird mit einem führenden #
    • VOR und NACH den = Zeichen ist immer ein Leerzeichen einzufügen

    Im Nano Editor die Datei dann mit STRG+O speichern und mit STRG+X den Editor wieder verlassen…

  3. Jetzt können wir uns schon der Steuerung des Interface widmen. Hierzu sind folgende Befehle wichtig:
    • Hochfahren des Wireguard Interfaces wg0
      sudo wg-quick up wg0
    • Runterfahren des Wireguard Interfaces wg0
      sudo wg-quick down wg0
    • Kombiniert man diese Befehle, wird ein Neustart des Tunnels initiiert:
      sudo wg-quick down wg0 && sudo wg-quick up wg0
    • Ein Neustart des Wireguard Service initiiert man mit:
      sudo systemctl restart wg-quick@wg0 
    • Den Status des Service prüft man dann mit:
      sudo systemctl status wg-quick@wg0
  4. Wenn die Konfig gemäß der eigenen Vorgaben abgeschlossen ist, geht’s ans Testen. Fahren wir also das Interface erstmalig hoch:
    sudo wg-quick up wg0


    Den Status des Wireguard Tunnels prüft man mit

    sudo wg

    Tunnel Down

    Tunnel Up

Der Wireguard Peer ist jetzt auf der Raspi-Seite vollständig installiert und konfiguriert. Jetzt ist es am Administrator, den Wireguard Peer in der Company oder auf welchen Standort man immer zugriefen möchte, zu konfigurieren. In meinem Fall läuft in einem Test Labor, an einem zentralen Standort, ein Ubuntu LTS 20.04 Server, auf dem ich ebenfalls Wireguard installiert habe. Dies wird mein Peer, auf den ich zugreifen werde. Wer gleiches plant, für den ist eventuell mein anderer Beitrag zum Thema Wireguard auf Ubuntu LTS 20.04 relevant.