Zum Inhalt springen

← Alle Notizen

Zwei Profile, eine Firewall — Fernzugang mit WireGuard

Wie aus festen Quelladressen ein Fernzugang für fünf Geräte wurde — geteilter und voller Tunnel, Regeln auf der Firewall statt im Client, und wo es gehakt hat.

  • WireGuard
  • OPNsense
  • SSH
  • NetworkManager

Bis zum 14. Oktober 2026 kam ich an meine Umgebung nur von zwei Orten heran: von zu Hause und aus dem Büro. Die Firewall ließ SSH zum Sprungserver und die Verwaltungsoberflächen nur von festen Quelladressen zu. Das ist sicher und unbequem. Unterwegs ging nichts, und im Notfall hätte ich erst nach Hause fahren müssen. Seit diesem Tag gibt es einen Fernzugang über WireGuard, eingerichtet auf iPhone, iPad, MacBook, Windows-PC und dem Arbeitsrechner.

Der Aufbau

WireGuard läuft auf der OPNsense, die ohnehin alle Netze trennt. Der Tunnel endet auf einer eigenen öffentlichen Adresse, die nur dafür da ist. Über dieselbe Adresse geht im vollen Tunnel auch der Verkehr ins Internet hinaus. Wer in einem Protokoll diese Adresse sieht, weiß sofort: Das kam aus dem Fernzugang.

Das Tunnelnetz ist 10.100.100.0/24 und liegt damit bewusst im internen /16. So greifen die bestehenden Regeln für interne Clients ohne Sonderfall, etwa die Sicht des Nameservers: Wer im Tunnel ist, bekommt die internen Antworten.

Jedes Gerät hat zwei Profile:

Profil Durch den Tunnel Wofür
Split die internen Netze, der Proxmox-Host, der Reverse Proxy Alltag. Alles andere geht direkt hinaus, wie ohne Tunnel.
Voll alles Fremde WLANs. Nach außen sieht man nur die Adresse des Fernzugangs.

Ein drittes Profil führt später direkt zum Proxmox-Host, an der OPNsense vorbei — für den Tag, an dem genau sie nicht läuft.

Die Firewall entscheidet, nicht der Client

Die Profile routen bewusst viel: das ganze interne Netz, das ganze eigene IPv6-Netz. Was davon erreichbar ist, entscheiden die Regeln auf der OPNsense. Ein Client-Profil ist eine Datei auf einem Gerät, das verloren gehen kann. Eine Regel auf der Firewall ist es nicht.

Die Regeln für den Tunnel, von oben nach unten:

  1. SSH zum Sprungserver, DNS, der Reverse Proxy, die Proxmox-Oberfläche und die Oberfläche der OPNsense — nur über ihre internen Adressen.
  2. Eine Notfallregel auf alle internen Netze. Sie ist ausgeschaltet und wird nur im Ernstfall angeknipst.
  3. Alles Interne gesperrt und protokolliert: die internen Netze, alle eigenen öffentlichen Adressen und die Firewall selbst. Sonst führte der volle Tunnel über die eigenen öffentlichen Adressen an den Regeln vorbei.
  4. SMTP gesperrt. Ein verseuchtes Gerät soll über die Adresse des Fernzugangs keinen Spam verschicken.
  5. Der Rest darf ins Internet.

Für SSH heißt das: direkt nur bis zum Sprungserver, alles Weitere über ihn — genau wie vorher. Geräte im Tunnel erreichen sich auch untereinander nicht.

Die Schlüssel der Geräte erzeugt ein Skript auf meinem eigenen Rechner, nicht die Firewall. Jeder Peer hat zusätzlich einen eigenen Pre-shared Key und darf nur seine eigene Tunneladresse verwenden. Ein verlorenes Gerät ist mit einem Klick gesperrt.

Stolpersteine

Die Antwort kam von der falschen Adresse. Der erste Handshake kam an, die Antwort nie. Die OPNsense schickte sie von ihrer Hauptadresse statt von der des Fernzugangs, und der Client verwarf sie. Eine Source-NAT-Regel für die eigenen WireGuard-Pakete, mit festem Quellport, setzt seitdem die richtige Absenderadresse.

Der Name, der durch sich selbst lief. Als Endpunkt einen Namen statt einer Adresse einzutragen, ist naheliegend. Der Name hat aber auch eine IPv6-Adresse, und die liegt im eigenen IPv6-Netz — das das Split-Profil durch den Tunnel schickt. In einem Netz mit IPv6 sollten die verschlüsselten Pakete also durch den Tunnel, den sie erst aufbauen. Die Apps auf iPhone, Mac und Windows fangen das ab, NetworkManager unter Linux nicht. Im ersten Testnetz fiel es nicht auf, weil dort kein IPv6 ankam. Der Endpunkt ist jetzt die IPv4-Adresse.

NetworkManager und der Schlüsselbund. Der Import einer WireGuard-Datei über nmcli legt den privaten Schlüssel im Schlüsselbund der Desktop-Sitzung ab. In der grafischen Oberfläche funktioniert die Verbindung dann, im Terminal nicht. Und nach einer Änderung in der Oberfläche fehlten Endpunkt und erlaubte Netze. Ein kleines Skript schreibt die Verbindung jetzt direkt als Datei, mit dem Schlüssel darin und mit DNS nur für die eigene Domain im Split-Profil.

Zwei VPNs auf einem Rechner. Der Arbeitsrechner hat zusätzlich das Firmen-VPN. Ist es an, zieht es alle Routen an sich, und WireGuard kommt nicht mehr hinaus. Beides gleichzeitig geht nicht. SSH soll trotzdem in jeder Lage den richtigen Weg nehmen: aus dem Büro und über das Firmen-VPN wie bisher über den Firmen-Sprungserver, mit WireGuard direkt. Die Entscheidung trifft die SSH-Konfiguration selbst, anhand der Route:

Match host srvjump00,pve00 exec "ip route get 10.100.1.2 | grep -qi 'dev oss-'"
    ProxyJump none
Match host srvjump00,pve00 exec "! timeout 1 bash -c '</dev/tcp/<firmen-sprungserver>/22'"
    ProxyJump none
Host srvjump00 pve00
    ProxyJump <firmen-sprungserver>

Geprüft wird die Route, nicht ob das Interface existiert. Sind beide VPNs an, gehört die Route dem Firmen-VPN, und die erste Regel greift richtigerweise nicht. Das -i an grep kam nachträglich: Das Interface heißt wie das Profil, mit großen Buchstaben, und zu Hause ging SSH deshalb zunächst ins Leere.

Wo ist die Begrüßung? Nach der Umstellung zeigte der Sprungserver kein MOTD mehr. Kein Fehler: Mit ControlMaster laufen weitere SSH-Aufrufe zehn Minuten lang durch die schon offene Verbindung. Der Server sieht keine neue Anmeldung, also gibt es auch keine Begrüßung.

Was noch kommt

  • Das Notfallprofil direkt zum Proxmox-Host, damit die OPNsense nicht der einzige Weg hinein ist.
  • Zwei Faktoren für die Oberflächen von OPNsense und Proxmox.
  • Die festen Quelladressen bleiben vorerst. Eine davon bleibt für immer — als Rückweg, falls WireGuard selbst streikt.

Was ich daraus mitnehme

Ein Fernzugang ist schnell eingerichtet. Die Arbeit steckt in den Fragen danach: Was darf durch, und wo wird das entschieden? Was passiert in einem Netz mit IPv6? Und was, wenn auf demselben Rechner schon ein anderes VPN läuft? Die Antworten gehören an eine Stelle, und diese Stelle ist die Firewall.

Fragen oder Anmerkungen? Gern über das Kontaktformular.