WireGuard VPN mit OPNsense und TunSafe

Dieser Artikel wird etwas umfangreicher und befasst sich zum einen mit der serverseitigen Konfiguration von WireGuard in OPNsense und zum anderen mit der clientseitigen Einrichtung von TunSafe unter Windows. Damit lässt sich mit relativ geringem Aufwand ein sicheres Road Warrior Setup realisieren. An einigen Stellen hole ich etwas weiter aus, um bestimme Dinge ausführlicher zu beleuchten. Wer gleich loslegen will, kann den folgenden Exkurs natürlich überspringen.

Exkurs

Auf OPNsense gehe ich nicht weiter ein, ich setze für diesen Artikel voraus, dass bereits eine funktionierende Umgebung existiert. Es folgen lediglich die notwendigen Schritte, um OPNsense den Umgang mit WireGuard beizubringen. Wer „näher am Anfang“ einsteigen und sich grundsätzlich mit OPNsense beschäftigen möchte, findet auf der Homepage des Projekts genügend Lesestoff.

Spannender ist da schon WireGuard, das neue, coole Kind auf dem Spielplatz der VPN-Lösungen. Der Konfigurationsaufwand für eine lauffähige und sichere VPN-Verbindung wird damit stark minimiert, weil der ganze Overhead und das ganze Legacy-Zeugs von OpenVPN nicht mitgeschleppt werden muss. Der Inhalt der Konfigurationsdateien beschränkt sich auf wenige Zeilen und trotzdem funktioniert’s am Ende wie erwartet.

Wer mehr über WireGuard erfahren will, findet natürlich alles wichtige auf der Projektseite. Außerdem hat Michael Larabel von Phoronix viele Informationen zusammengetragen und auch in der deutschsprachigen Medienlandschaft (heise.de, Paywall) stehen Informationen bereit.

Serverkonfiguration in OPNsense

Die Dokumentation von OPNsense zur Einrichtung von WireGuard ist nicht schlecht und dient auch als Basis für diesen Artikel. Allerdings bin ich selbst über ein oder zwei Dinge gestolpert, die unklar waren oder die ich schlicht anders gelöst hätte. Ich werde dazu noch Kontakt mit den Verantwortlichen aufnehmen, ob es sinnvoll ist, die Doku an diesen Punkten zu ergänzen oder zu verändern.

Installation des WireGuard Plugins

Da sich WireGuard aktuell noch in der Entwicklungsphase befindet, nicht nur unter Linux sondern auch unter FreeBSD & Co., ist das Plugin noch nicht in den stabilen Quellen von OPNsense zu finden. Daher ist eine Installation über die Shell nötig. Also fix per SSH auf der Firewall eingeloggt und folgenden Befehl abgesetzt:

pkg install os-wireguard-devel

Damit wird die aktuelle Entwicklerversion des Plugins installiert und sollte bei zukünftig vorhandenen Updates auch automatisch mit aktualisiert werden. Ein Wechsel des OPNsense Release Type von Production auf Development ist nicht erforderlich.

Im linken Menü des OPNsense Webinterfaces sollte es nun unterhalb von VPN den Punkt WireGuard geben. Dort wird die gesamte Konfiguration vorgenommen.

Erzeugen der WireGuard Serverinstanz

Im Register Local wird mit einen Klick auf + in der rechten Ecke ein neuer Server angelegt. Wichtig sind die Felder Name, Listen Port und Tunnel Address. Der Rest bleibt (vorerst) leer oder wird beim Speichern automatisch erzeugt.

Im Feld Name wird ein eindeutiger, aus den Zeichen A-Z, a-z, 0-9 bestehender Name vergeben. Leer- oder Sonderzeichen sind nicht zulässig. Das Feld Listen Port gibt den Port des Servers an, unter welchem dieser später erreichbar sein soll. Dieser Wert lässt sich grundsätzlich frei wählen; viele Anleitungen verwenden 51820, weshalb dieser auch hier exemplarisch verwendet wird. Als letztes muss überlegt werden, welches Netz für die VPN-Verbindungen zum Einsatz kommen soll. Dieses wird in CIDR Notation (10.0.0.1/24) in das Feld Tunnel Address eingetragen.

Die privaten Adressblöcke haben den Nachteil, dass man sich in freier Wildbahn theoretisch in ein WLAN-Netz einwählen könnte, welches ebenfalls den hier verwendeten Adressbereich nutzt. In dieser speziellen Konstellation wäre somit keine VPN-Verbindung zu unserem WireGuard Server möglich. Öffentliche IPv4-Adressen dürfen auch auf gar keinen Fall verwendet werden, also was tun? Abhilfe schafft die Richtlinie RFC 6598. Diese reserviert für das sogenannte Carrier-Grade-NAT den Adressbereich 100.64.0.0/10 (Danke an dieser Stelle an Carsten Strotmann von heise.de für diesen Vorschlag). Dieser Adressbereich wird niemals öffentlich verwendet werden und sollte auch bei einem korrekt konfigurierten (= den Spielregeln der jeweiligen RFCs entsprechenden) WLAN nicht zum Einsatz kommen. Ein /10er Netz wäre jedoch sehr oversized für den Privatgebrauch, daher begnügen wir uns mit der gebräuchlichen /24er Subnetzmaske und haben somit Platz für theoretisch 253 einzelne VPN-Clients in unserem Netz.

Lange Rede kurzer Sinn, bei Tunnel Address tragen wir 100.64.0.1/24 ein und beenden vorerst die Serverkonfiguration mit einem Klick auf Save changes.

TunSafe Client Installation und Konfiguration – Teil 1

An dieser Stelle wird es etwas tricky, denn eigentlich müssten wir im Verlauf der Anleitung immer zwischen TunSafe und OPNsense hin- und herspringen. Ich versuche jedoch, das auf ein Minimum zu reduzieren und eine einigermaßen logische Reihenfolge der einzelnen Schritte zu finden.

Der Einfachheit halber verwenden wir den fertigen Installer von TunSafe. Wer bereits OpenVPN auf dem Rechner installiert hat, kann theoretisch auch das Standalone Zip File verwenden. Die Installation selbst ist nicht der Rede wert und läuft einfach mit den Standardeinstellungen bis zum Ende durch.

Nach dem Start des Programms wird der User* mit einer Standardkonfiguration begrüßt. Erste Amtshandlung sollte nun sein, ein neues Schlüsselpaar für unseren Client zu generieren. Dieses Schlüsselpaar ist für die nachfolgenden Schritte essenziell wichtig. Dieser Vorgang wird über File > Generate Key Pair… eingeleitet. Ein Klick auf Randomize erzeugt ein passendes Schlüsselpaar.

Die hier gezeigten Schlüssel dienen natürlich nur als Beispiel und sollten unter keinen Umständen für eine echte Konfiguration verwendet werden!

Beide Schlüssel kopieren wir uns für die spätere Verwendung in eine Textdatei und verwahren diese an einem sicheren, für niemand anderen zugänglichen Ort. Oder wir speichern die Datei gar nicht und drucken das Schlüsselpaar ganz traditionell auf Papier aus.

Clientkonfiguration in OPNsense

Es erfolgt ein Wechsel zurück ins Webinterface von OPNsense. Unter VPN > WireGuard > Endpoints wird nun unser erster Client angelegt. Wie gehabt mit einem Klick auf das + in der rechten Ecke.

Wichtig sind die Felder Name, Public Key und Tunnel Address. Name ist klar, es gelten die gleichen Bedingungen wie bei der Serverkonfiguration auch; Public Key enthält den öffentlichen Schlüssel, den wir gerade in TunSafe generiert haben (die rote Zwei); Tunnel Address wird die Adresse, die unser VPN-Client zugewiesen bekommen soll, wieder in CIDR Notation und natürlich aus dem in der Serverkonfiguration festgelegten Netz. Um beim Beispiel zu bleiben, wäre 100.64.0.10/32 möglich. Wichtig ist beim Road Warrior Setup, dass als Subnetzmaske /32 verwendet wird. Es soll ja erreicht werden, dass ein festgelegter Client genau eine festgelegte IP-Adresse verwendet.

Wichtig ist, dass der Haken bei Enabled gesetzt ist, die restlichen Felder bleiben leer, Save changes speichert die getätigten Änderungen.

Verknüpfung von Client und Server

Im nächsten Schritt muss dem WireGuard Server der Client auch noch bekannt gemacht werden. Dieser Schritt wird gerne vergessen und man wundert sich, warum keine Verbindung zu Stande kommt, obwohl augenscheinlich alles passt. Also das Verknüpfen bitte nicht vergessen.

Man wechselt dazu wieder in das Register Local und bearbeitet den vorhandenen Server.

In der Dropdown-Liste bei Peers wählt man den erzeugten Client aus, sodass dieser mit einem Haken versehen wird. Zusätzlich sollte man gleich prüfen, ob der Haken bei Enabled gesetzt ist. Mit Save changes wird der Vorgang abgeschlossen. Jetzt wäre außerdem ein guter Zeitpunkt, sich den Public Key des Servers (die grüne Eins) in einer Textdatei abzuspeichern. Dieser Key wird später noch in der TunSafe Konfiguration benötigt.

Zum Abschluss der WireGuard Konfiguration sollte im Register General noch der Haken bei Enable WireGuard gesetzt werden. Ein Klick auf Save beendet die Konfiguration.

Firewall Einstellungen in OPNsense

Damit überhaupt eine Kommunikation von Extern stattfinden kann, muss noch eine Firewallregel erstellt werden. Unter Firewall > Rules > WAN wird eine neue Regel mit folgenden Settings hinzugefügt.

Der Rest bleibt default. Diese Regel wird abgespeichert und die Firewall Regeln werden einmal neu durchgeladen. Alles weitere passiert jetzt nicht mehr in der Firewall sondern auf dem Client.

Dieses Setup sorgt nur dafür, dass das interne Netzwerk der OPNsense Firewall erreicht wird. Der Internettraffic läuft weiterhin ungetunnelt an der VPN-Verbindung vorbei. Das lässt sich ändern, siehe Punkt 2c der offiziellen Anleitung.

Ich werde die Anleitung in Zukunft noch ergänzen, um diesem Umstand Rechnung zu tragen. Denkbar wäre auch, zwei verschiedene Konfigurationen anzulegen, einmal eine nur für den Zugriff ins Heimnetz, um z.B. NAS-Laufwerke zu erreichen und eine andere, bei der auch der gesamte Webtraffic getunnelt wird.

TunSafe Client Installation und Konfiguration – Teil 2

TunSafe liefert im Standard bereits eine Beispielkonfiguration mit. Diese kann mit einem Klick auf Edit Config bearbeitet werden. Folgende Konfiguration dient als Beispiel und muss mit den jeweils korrekten Werten bestückt werden.

[Interface]
PrivateKey = PRIVATE_KEY_DES_CLIENTS_(DIE_ROTE_EINS)

# Switch DNS server while connected
# DNS = 8.8.8.8 

Address = IP_DES_CLIENTS_CIDR

# Whether to block all access to Internet that doesn't go through tunsafe.
# Note that Internet will keep being blocked even after TunSafe is restarted.
# Possible values (comma separated):
#  route - Blocks all traffic using null route entries
#  firewall - Blocks all traffic except TunSafe through the Windows firewall
#  on - Uses the default block mechanism
#  off - Turns off blocking
# BlockInternet = route, firewall

[Peer]
PublicKey = PUBLIC_KEY_DES_SERVERS_(DIE_GRUENE_EINS)
AllowedIPs = EUER_NETZ_ZU_HAUSE_CIDR
Endpoint = EURE_OEFFENTLICHE_IP:51820
PersistentKeepalive = 25

Als Hinweis gleich vorweg: alles mit # am Anfang ist natürlich auskommentiert und kommt nicht zur Anwendung.

Widmen wir uns zunächst dem [Interface]-Teil. PrivateKey muss der in TunSafe generierte private Schlüssel sein. Auf den Screenshots als rote Eins zu erkennen. Address ist die IP-Adresse, welche wir dem Client im Webinterface von OPNsense zugewiesen haben. In unserem Beispiel wäre das die 100.64.0.10/24. Wichtig ist das /24er Subnetz am Ende. An dieser Stelle weisen wir zwar die IP-Adresse korrekt zu, passen die Subnetzmaske aber unserem gesamten VPN-Netz an. Das hat somit seine Richtigkeit und ist in der offiziellen Doku etwas konfus. Unter DNS lässt sich für diese Verbindung noch ein DNS-Server spezifizieren. Das könnte theoretisch die interne IP-Adresse der OPNsense sein.

Der [Peer]-Teil ist etwas umfangreicher aber eigentlich auch selbsterklärend. Der PublicKey muss der öffentliche Schlüssel des WireGuard Servers sein, auf den Screenshots die grüne Eins. Unter AllowedIPs werden die Netze angegeben, die durch den Tunnel sollen. Also logischerweise euer Heimnetz, in welches ihr die Verbindung aufbauen wollt. Endpoint ist die öffentliche IP-Adresse, die euer Provider eurer Firewall zugeteilt hat. Wer in OPNsense DynDNS verwendet, kann dort auch den passenden Hostnamen eintragen. Direkt angeschlossen an die IP folgt der Port, welchen ihr bei der Serverkonfiguration vergeben habt. In unserem Beispiel die 51820.

Fazit

Trotz des vermeintlich langen Textes ist die Konfiguration von WireGuard um Längen einfacher als die von OpenVPN. Es gibt keine Zertifikate mit Ablaufdatum mehr, um die man sich kümmern müsste, keine speziellen Konfigurationen, um Site-to-Site-Verbindungen herstellen zu können, keine 15 verschiedenen Verschlüsselungsalgorithmen, mit denen man sich beschäftigen muss, sondern je ein relativ einfach gehaltenes Konfigurationsfile auf Server- und Clientseite und das war’s. Ich bin jedenfalls sehr angetan von der Lösung und bin gespannt, was sich in Zukunft noch für Möglichkeiten damit ergeben werden. Und nun wünsche ich viel Erfolg beim Nachmachen.

12 Gedanken zu “WireGuard VPN mit OPNsense und TunSafe”

    1. Auf OPNsense Seite sicherlich. Ich hab’s nicht verifiziert, aber das ist bei allen Feldern, in denen Schlüssel eingetragen werden so. Auf Windows-Seite nur insofern, dass wenn TunSafe unterhalb von %ProgramFiles% liegt, zumindest UAC anschlagen sollte, wenn etwas ist. Aber die Problematik besteht ja mit OpenVPN unter Windows genauso.

  1. Hi.
    Ich habe es mit der Anleitung versucht — bekomme aber immer nur „Sending handshake; retrying …“.

    Zudem habe ich gesehen, dass unter OPNSense -> Firewall auch ein Aschnitt speziell für Wireguard auftaucht. Da muss man nichts eintragen?

    Ich habe mir TunSafe sowohl auf dem Smartphone als auch auf einem WinClient angesehen. Mir ist nicht ganz klar, ob ein generiertes Key-Pair auch sofort genutzt wird oder ob es sofort wieder verworfen wird, wenn man den Eintrag nicht nutzt? Im Smartphone kann ich zwar den private Key mit copy & paste in eine Datei schreiben; nicht aber den publick Key. Finde ich ebenfalls sehr merkwürdig … bzw hätte ich es eigentlich eher umgekehrt erwartet?

    Vielleicht hat ja jemand einen guten Tipp…

    1. Kurze Antwort an mich selbst: MIttlerweile läuft die Verbindung sowohl vom Android-Smartphone als auch vom Client (Win10 und Ubuntu). Ich habe zusätzlich einen PSK erzeugt, der mit in die .conf eingetragen wird. Auch das funktioniert hier jetzt.

      Man kann es einen Bug unter TunSafe (Android) bezeichnen, dass man den PrivateKey nicht kopieren kann — aber andererseits kann man die .conf-Datei auch auf einem (Win)Client erzeugen, dann einen QR-Code daraus machen und sie dann auf dem Smartphone einscannen. Das geht mindestens genauso schnell…

      Es bleibt dennoch eine Frage: Ich müsste doch das Webinterface von OPNSense erreichen können (LAN-Adresse), wenn ich verbunden bin? Das will hier nicht. Fehlt evtl doch noch eine FW-Regel oder Route?

        1. Super — danke! Das hilft natürlich enorm weiter. [Ich hatte bisher einen IPFire in Betrieb — da waren viele Dinge voreingestellt. Man muss sich zunächst daran gewöhnen, dass OPNSense eine *richtige* FW ist 🙂 … ]

          Unter Ubuntu steht die Verbindung mit „wg-quickwg-quick up meine.conf“ ja wirklich in Null-Komma-Nix!

          Eine Frage hatte ich übrigens noch vergessen:
          Wie muss ich mir das vorstellen, wenn man (zusätzlich) mit einem PSK arbeitet: Ist das dann so wie bei einem Zugang zu einem WLAN: Wer den PSK kennt, kommt rein? Man muss den PubKey aber doch trotzdem im Server einstellen? Daher ist mir die Funktion bzw der Vorteil nicht ganz klar…

          Schönen Gruß!

          1. Genau, der PSK ist optional und dient als zusätzliches Sicherheitsmerkmal. Aber wer nur den PSK kennt, kommt trotzdem nicht rein. Also nicht wie beim WLAN. Andersrum lässt sich das besser erklären. Wer aus irgendwelchen Gründen die privaten Schlüssel erbeutet, kommt ohne PSK trotzdem nicht weiter.

        2. Noch zwei Fragen … im letzten Bild hast du bei „Outbound“ ein Netzwerk/24 angegeben. Um welches Netz handelt es sich da? Ist das dein Wireguard-Netz?

          Ich würde auch gerne bei den „Anti-Lockout-Regeln“ Port 22 hinzufügen — aber ich finde leider die Stelle nicht, wo ich diese Regel bearbeiten/hinzufügen kann … Idee?
          Danke nochmal.

          1. Genau, das ist das Wireguard-Netz. Dafür muss auch NAT gemacht werden, weil sonst kein Traffic mit dem Internet stattfinden kann. Die „Anti Lockout Rule“ wird automatisch erweitert, je nachdem welche Dienste du direkt auf der Firewall erlaubst. Damit dort SSH auftaucht und du im Fall der Fälle per SSH an die Firewall kommst, genügt es, den SSH-Zugriff auf die Firewall zu aktivieren. Unter System > Settings > Administration wird das gemacht. Sobald da SSH aktiv ist, taucht Port 22 auch in der Anti Lockout Rule auf.

  2. Hi. Ich konnte ’ne Weile nicht weitermachen … aber heute habe ich nochmal die Firewall-Regeln nachgetragen. Es bleibt leider dabei: Die Verbindung steht (sowohl vom Ubuntu Client als auch vom Smartphone mit TunSafe) aber ich komme nicht weiter.
    Selbst ein ping auf die Wireguard-Server-IP geht nicht durch:
    „PING 100.64.0.1 (100.64.0.1) 56(84) bytes of data.
    From 100.64.0.10 icmp_seq=1 Destination Host Unreachable
    ping: sendmsg: Der notwendige Schlüssel ist nicht verfügbar“

    „ip r“ zeigt mir:
    100.64.0.0/24 dev wg0 proto kernel scope link src 100.64.0.10
    Sieht also eigentlich alles richtig aus?!
    Die FW-Regel unter „Wireguard“ ist ebenfalls eingetragen — aber ich erreiche das OPNSense-Webinterface nicht.
    Hast du noch einen guten Tipp?

      1. Und noch eine Antwort auf die Antwort …. ich habe nach ein paar Versuchen festgestellt, dass wireguard offenbar noch nicht soooo stabil läuft. Bsp: Ich wollte einen zweiten Zugang einrichten, der auf 100.64.0.11/24 läuft. Das klappte nicht. Sobald ich serverseitig bei den wireguard-Settings nochmal auf „Speichern“ geklickt habe, ist die komplette OPNSense-VM reproduzierbar abgestürzt und hat einmal sogar ein unbrauchbares System hinterlassen (Dateisystem zerschossen). Bis das produktiv läuft, wird also offenbar noch etwas Zeit vergehen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.