FritzBox - Site to Site VPN zu pfSense mit WireGuard ohne Tunnel NAT
Aus znilwiki
Changelog:
- 17.12.2024 erste Version
Das ist die erste Version der Anleitung, es wird viel Hin- und Hergesprungen und das ein oder andere lässt sich sicherlich optimieren - das kommt dann später.
Vorwort
Dieser Artikel war eine schwere Geburt, ich habe 6 Stunden gebraucht bis alles so funktioniert hat wie es soll.
Der Tunnel stand schon nach ein paar Minuten, jedoch hatte ich das Problem das ich aus meinem lokalen FritzBox-Netzwerk alles drüben im pfSense-Netzwerk erreichen konnte - aber nicht umgekehrt. Bzw. nur sporadisch, einigen Clients konnten untereinander, andere nicht.
Pings gaben solche komischen Meldungen von sich:
PING 192.168.1.80 (192.168.1.80) 56(84) bytes of data. 64 bytes from 10.100.1.2: icmp_seq=1 ttl=126 time=32.2 ms (DIFFERENT ADDRESS!)
Das 10.100.1.x ist mein Tunnelnetz, er hat immer in beide Richtungen NAT gemacht. Nicht ganz richtig, auf pfSense-Seite war es schon richtig, aber die Fritzbox hat NAT gemacht.
Wie auch immer stand die Lösung im Internet und war über Google abrufbar ... wenn man denn die richtigen Suchbegriffe verwendet.
Die Anleitung hier ist nun aus rund einem Duzend anderer Anleitung entstanden.
Und niedergeschrieben habe ich es damit ich das überhaupt noch mal neu auf die Reihe bekomme.
Angefangen habe ich das ganze überhaupt weil ich zwischen mir zu Hause und einen Mietserver jeden Abend viele Backups hin- und herschiebe. Und das ganze geht mit gemächlichen 10Mbyte pro Sekunde von statten. Dabei hat meine FritzBox 600MBit/s Download und 300MBit/s Upload, mein Mietserver ist symmetrisch mit 250MBit/s im Internet.
Über das Programm iperf3 konnte ich den Unterschied messen:
IPSec
[ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 56.4 MBytes 47.3 Mbits/sec sender [ 4] 0.00-10.00 sec 56.4 MBytes 47.3 Mbits/sec receiver
Wireguard
[ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 79.4 MBytes 66.6 Mbits/sec sender [ 4] 0.00-10.00 sec 79.3 MBytes 66.5 Mbits/sec receiver
Wobei die Werte etwas schwanken, je nachdem wieviel gerade auf dem Tunnel sonst noch los ist.
Das sind immerhin um die 40% mehr auf der gleichen Verbindung.
Ausgangslage
Das geplante Konstrukt sieht so aus:
Die FritzBox hat folgende Einstellungen:
Interne IP.........: 192.168.1.200 Internes Netzwerk..: 192.168.0.0 Subnetzmaske.......: 255.255.252.0 Subnetzmaske Suffix: 22 Externe IP.........: Dynamisch, ändert sich täglich Dynamisches DNS ...: rpdxxxxxxxxxxxkm.myfritz.net
Die dynamische DNS Adresse findet Ihr unter
Internet => MyFRITZ!-Konto => MyFritz!-Internetzugriff
Dazu müsst Ihr MyFRITZ! für diese Box aktiviert haben.
Die pfSense hat diese Einstellungen:
Interne IP.........: 192.168.128.1 Internes Netzwerk..: 192.168.128.0 Subnetzmaske.......: 255.255.255.0 Subnetzmaske Suffix: 24 Externe IP.........: 37.187.93.131
Die pfSense hat eine feste externe IP-Adresse.
Im WireGuard Tunnel wird das folgende Netzwerk genutzt (willkürlich von mir festgelegt):
Netzwerk....: 10.100.2.0/30 Subnetzmaske: 255.255.255.252 IP pfSense..: 10.100.2.1 IP FritzBox.: 10.100.2.2
Das ganze ergibt einen WireGuard-Server auf der pfSense mit nur 2 Teilnehmern, der FritzBox und der pfSense selbst.
Auf der pfSense Teil 1
WireGuard installieren
Als erstes Installieren wir auf der pfSense ggf. das Paket "WireGuard" nach.
Dazu gehen wir unter
System => Package Manager => Available Packages
und suchen dort nach
wireguard
und installieren das gefundene Paket:
WireGuard aktivieren und starten
Unter
VPN => WireGuard => Settings
Setzt den Haken bei (1) und nehmt diese bei (2) und (3) raus, das erleichtert die Fehlersuche später.
Dann speichern.
Tunnel konfigurieren
Unter
VPN => WireGuard => Tunnels
fügen wir einen neuen Tunnel hinzu:
Bei (1) gebt Ihr eine griffige Beschreibung ein. Dieser Tunnel bedient nur eine Gegenstelle weshalb ich einen entsprechenden Namen genommen habe.
Bei (2) wird der Port festgelegt auf dem der Wireguard-Server lauscht. 51820 ist der Standardport von WireGuard, ihr könnt aber auch fast jeden anderen Port zwischen 1 und 65535 nehmen. In der Praxis nehmt keinen Port unter 1024.
Dann klickt Ihr (3) auf Generate worauf hin er einen Private und einen Public Key erstellt.
Den Public key (4) kopiert ihr euch weg, das ist der Public Key eurer pfSense und den brauchen wir später noch.
Bei Bedarf könnt Ihr die Einstellungen für den Tunnel aber noch mal aufrufen und den Key nochmals kopieren.
Dann den Tunnel (5) speichern.
WireGuard Server von außen erreichbar machen
Unter
Firewall => Rules => WAN
erstellen wir eine neue Regel um den WireGuard-Server auf Port 51820 aus dem Internet erreichbar zu machen:
Interface (1) sollte schon auf WAN stehen, und
Address Family schon auf IPv4
Protocol (2) auf UDP (WireGuard kann explizit nur UDP),
bei Destination Port Range (3) tragen wir in beide Felder den Port 51820,
bei Description (6) eine passende Beschreibung und dann (6) speichern.
WireGuard Schnittstelle hinzufügen
Wir gehen zu
=> Interfaces => Assignments
und fügen unten die verfügbare tun_wg0 Schnittstelle hinzu:
Im Anschluss klicken wir vorne auf OPT1 um die Schnittstelle zu konfigurieren:
Bei Enable (1) aktivieren wir die Schnittstelle und benennen diese bei Description (2) um.
Wir wollen IPv4 Configuration Type (3) eine statische IP-Adresse vergeben.
Die MTU (4) setzen wir gemäß der [offiziellen Anleitung von netgate|https://docs.netgate.com/pfsense/en/latest/recipes/wireguard-s2s.html#assign-interface] auf 1440 (reiner IPv4 Betrieb).
Bei IPv4 Address (5) setzen wir die Tunneladresse für die pfSense
10.100.2.1
die ich so festgelegt habe. Vergesst bei (6) nicht die Subnetmaske bzw. das Suffix auf 30 zu setzen.
Dann Save (7) speichern.
Anmerkung: im Gegensatz zur Netgate-Anleitung setzen wir hier kein Gateway für die Schnittstelle! Dadurch würde die pfSense anfangen für die Schnittstelle NAT zu machen, wir wollen aber das geroutet wird.
WireGuard Gateway hinzufügen
Weiter geht es unter
System => Routing => Gateways
Dort setzen wir zunächst unten das Default gateway IPv4 auf das Gateway des WAN-Interfaces:
Speichern nicht vergessen!
Jetzt per + Add ein neues Gateway hinzufügen:
Unter Interface (1) Wählen das zuvor erstellte Interface aus,
Address Family sollte bereits auf IPv4 stehen,
bei Name wieder ein passende Bezeichnung,
als Gateway Tragen wir hier die
10.100.2.2
ein, das die die IP-Adresse die später die FRITZ!Box im Tunnel bekommen wird.
Nun Save (5) speichern.
Statische Route hinzufügen
Wir wechseln auf den Reiter Static Routes
System => Routing => Static Routes
und fügen per + Add eine neue Route hinzu:
Destination network (1) ist das Netzwerk hinter der FRITZ!Box, vergesst (2) den Netzwerksuffix nicht anzupassen!
Bei Gateway wählen wir das zuvor erstellte Gateway aus.
Jetzt noch eine passende {{code|Description\\ (4) und dann Save (5) speichern.
Firewall Regel für Datenverkehr im WireGuard Tunnel erstellen
Im Moment würden in einem Tunnel keine Daten übertragen werden weil es dafür keine passende Regel fehlt - die erstellen wir nun:
Firewall => Rules => WG_GLASFASER
Der Name entspricht dem Namen den Ihr der Schnittstelle gegeben habt.
Mit Add fügen wir eine neue Regel hinzu:
Action (1) sollte schon auf Pass stehen,
genauso wie Interface (2) schon auf unserer WireGuard-Schnittstelle stehen sollte.
Address Family (3) auf IPv4 stehen.
Mit dem Protocol (4) auf Any erlauben wir sämtlichen Datenverkehr im Tunnel, neben TCP und UDP z.B. auch ICMP für das Pingen.
Das könnte Ihr natürlich bei Bedarf einschränken, für den ersten Test erlaube ich aber erst einmal alles.
Jetzt noch eine passende Description (5) und dann Save (6) speichern.
Auf der FritzBox Teil 1
Auf der FRITZ!Box werden wir eine Konfigurationsdatei importieren. Der normale Dialog gibt uns nicht genügend Einstellmöglichkeiten (insbesondere wenn Ihr mehr als ein Netzwerk über den Tunnel erreichbar machen wollt).
Wir brauchen aber einen Public- und Private-Key für die FRITZ!Box, diese müssen wir deshalb selber erzeugen.
Private und Public Key erzeugen Variante 1: SSH (Linux)
Um einen Privaten und Öffentlichen Schlüssel zu erzeugen, brauchen wir eine WireGuard-Installation.
Nun ja, auf der pfSense ist WireGuard installiert, also könnten wir diese nutzen.
Dazu schalten wir auf der pfSense den SSH-Zugang unter
System => Advanced => Admin Access
und dann im Abschnitt Secure Shell den Haken setzen:
und ganz untern Speichern.
Jetzt verbinden wir uns z.B. per puTTY mit der pfSense,
Benutzername und Passwort sind die gleichen wie für das Webinterface.
Es kommt das pfSense Menü:
VMware Virtual Machine - Netgate Device ID: ad2238d8e36e61ddd3bc *** Welcome to pfSense 2.7.2-RELEASE (amd64) on pfSenseDEMO *** WAN (wan) -> vmx0 -> v4/DHCP4: 192.168.0.31/22 LAN (lan) -> vmx1 -> v4: 192.168.33.1/24 WG_GLASFASER (opt1) -> tun_wg0 -> v4: 10.100.2.1/30 0) Logout (SSH only) 9) pfTop 1) Assign Interfaces 10) Filter Logs 2) Set interface(s) IP address 11) Restart webConfigurator 3) Reset webConfigurator password 12) PHP shell + pfSense tools 4) Reset to factory defaults 13) Update from console 5) Reboot system 14) Disable Secure Shell (sshd) 6) Halt system 15) Restore recent configuration 7) Ping host 16) Restart PHP-FPM 8) Shell Enter an option:
Wir wechseln per 8) zu Shell und erzeugen mit
wg genkey
einen privaten Schlüssel (den wir uns wegspeichern), Ausgabe:
[2.7.2-RELEASE][admin@pfSenseDEMO.home.arpa]/root: wg genkey sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE=
Mit dem diesem privaten Key erzeugen wir nun noch unseren öffentlichen Schlüssel:
echo sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE= | wg pubkey
Ausgabe:
[2.7.2-RELEASE][admin@pfSenseDEMO.home.arpa]/root: echo sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE= | wg pubkey pp0mSNwJj+OHxfEtjgl8hWmQfKsMR4eiDjXgQfodzhU=
Dem 2. Befehl übergeben wir also per echo den privaten Key aus dem ersten Befehl.
Beim obigen Beispiel ist also als Ergebnis das folgende herausgekommen:
Private Key: sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE= Public Key.: pp0mSNwJj+OHxfEtjgl8hWmQfKsMR4eiDjXgQfodzhU=
Beide kopieren wir uns weg, per
exit 0
können wir die SSH-Sitzung wieder verlassen.
Private und Public Key erzeugen Variante 2: Windows oder macOS Software
Ich habe hier die Windows-Software verwendet, mit der macOS Version wird es vermutlich genauso gehen.
Die könnte Ihr unter https://www.wireguard.com/install/ herunterladen und installieren:
Wie Ihr seht kann man es auch leicht unter Linux installieren, das wären dann die Befehle aus der Variante 1
Nach der Installation kann man die WireGuard-Software über das Startmenü starten (oder die Oberfläche über das Symbol in der Taskleiste öffnen):
Wir fügen einen leeren Tunnel hinzu (oder STRG + N drücken):
Und schon haben wir einen Privaten (2) und Öffentlichen Schlüssel (1).
Für mehr brauchte ich den Client nicht.
MyFRITZ!-Adresse ermitteln
Nun geht es tatsächlich kurz auf die FritzBox-Oberfläche:
Internet => MyFRITZ!-Konto
Von dort kopiert ihr euch die Adresse:
und sichert diese Weg.
Auf der pfSense Teil 2
Im Abschnitt zuvor haben wir nun folgenden Daten gesammelt / erstellte:
Private Key.....: sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE= Public Key......: pp0mSNwJj+OHxfEtjgl8hWmQfKsMR4eiDjXgQfodzhU= MyFritze-Adresse: rpdxxxxxxxxxxxkm.myfritz.net
Mit diesen Daten können wir nun auf der pfSense den WireGuard-Peer anlegen
WireGuard Peer anlegen
Wir gehen zu
VPN => WireGuard => Peers
und fügen mit + AddPeer einen neuen hinzu:
Bei Tunnel (1) wählen wir den WireGuard-Tunnel aus (es sollte nur den einen geben),
eine passende Description (2) Beschreibung setzen,
den Haken bei Dynamic Endpoint (3) entfernen, dadurch erweitert sich die unteren Optionen.
Bei Endpoint (4) kopiert Ihr die MyFRITZ!-Adresse eurer Box hinein,
den Port (5) setzen wir zunächst auf 51820. Die FRITZ!Box wird einen anderen, zufälligen Port wählen, diesen korrigieren wird dann später.
Keep Alive (6) setzen wir auf 25 was sich als Standardwert etabliert hat - dadurch wird der Tunnel alle 25 Sekunden am Leben erhalten, auch wenn kein Datenverkehr stattfindet.
Beim Public Key (7) kopieren wir den Public Key der FRITZ!Box hinein den wir zuvor erzeugt haben.
Den Pre-shared Key erzeugen wir über den Generate Button rechts daneben. Den Key kopiert Ihr euch heraus, den brauchen wir gleich der Erstellung der Konfigurationsdatei der FRITZ!Box.
Bei Allowed IPs fügen wir zunächst die Tunnel-Adresse der FRITZ!Box (9) hinzu, beachtet die Subnetzmaske/Suffix (10) {{code|32}, damit ist nur diese IP erlaubt.
Danach das LAN-Netzwerk hinter der FRITZ!Box (11) mit passender Subnetmaske/Suffix (12).
Dann Save Peer (13) speichern.
Auf der FritzBox Teil 2
Nun haben wir alle Daten für die Konfigurationsdatei der FRITZ!Box zusammen, das letzte fehlende Element war der Pre-shared Key.
Konfigurationsdatei für FRITZ!Box erzeugen
Wir erstellen eine leere Textdatei mit dem Editor eurer Wahl,
Vorzugsweise mit der neueren Notepad-Version von Windows 11 oder Notepad++ mit folgendem Inhalt:
[Interface] PrivateKey = sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE= Address = 192.168.1.200/22 DNS = 192.168.128.1 [Peer] PublicKey = MQ8iAsZWrBccP7lATewtiibOmeRGPC/WbuIo2CSufww= PresharedKey = 8AI/55Iv9r51JKi0go3CtcEhapjUo/uxCMkBYkswhK8= AllowedIPs = 192.168.128.0/24,10.100.2.1/32 Endpoint = 37.187.93.131:51820 PersistentKeepalive = 25
Die Einstellungen im Detail (bitte genau beachten!!!!)
PrivateKey = sBnGGKW0g5rOpIy+RobSYELspEDy3qcANDQnZ5XJuWE=
Ist der private Schlüssel den wir zuvor für die FRITZ!Box erzeugt haben. Den Public Key haben wir ja auf der pfSense beim Peer eingetragen.
Address = 192.168.1.200/22
Das ist die IP-Adresse welche die FRITZ!Box im Tunnel bekommt. Häh? Dann müsste dort aber ja 10.100.2.2/30 stehen?
Richtig. Und es funktioniert dann auch wie gedacht. ABER dann macht die FRITZ!Box NAT, alle Clients im Netz hinter der pfSense sehen dann statt des LAN-Netzwerkes hinter der FRITZ!Box nur noch diese Tunneladresse.
Die 192.168.1.200/22 ist die interne IP-Adresse der FRITZ!Box mit passenden Suffix (Im Standard also 192.168.178.1/24).
Das ist eine Besonderheit der FritzBox, diese holt sich dann trotzdem die passende IP-Adresse von der pfSense - und routet dann ohne NAT zwischen den Netzwerken. Schönen Dank an [m0nji|https://forum.netgate.com/topic/171526/wireguard-fritzbox-pfsense/10] der das herausbekommen hat.
DNS = 192.168.128.1
Das ist die pfSense, übergeben als DNS-Server. Die FRITZ!Box fügt diesen den WireGuard-Einstellungen hinzu. Den Sinn dahinter habe ich noch nicht verstanden, es wird in den meisten Beispielen im Internet so gemacht. Ggf. fliegt das in einer späteren Version dieser Anleitung wieder raus. Vermutlich ist das wichtig wenn man den gesamten Datenverkehr über die Verbindung umleitet.
PublicKey = MQ8iAsZWrBccP7lATewtiibOmeRGPC/WbuIo2CSufww=
Das ist der Public Key der pfSense! Zu finden in den Einstellungen des Tunnels (VPN => WireGuard => Tunnels => der erstellte Tunnel)
PresharedKey = 8AI/55Iv9r51JKi0go3CtcEhapjUo/uxCMkBYkswhK8=
Den PresharedKey haben wir erzeugt als wir den Peer auf der pfSense angelegt haben (VPN => WireGuard => Peers => der erstellte Peer)
AllowedIPs = 192.168.128.0/24,10.100.2.1/32
Das ist zum einen das Netzwerk hinter der pfSense mit Suffix 192.168.128.0/24,
zum anderen die IP-Adresse der pfSense im Tunnel 10.100.2.1/32, auch hier mit dem 32er Suffix, also nur dieser Host.
Endpoint = 37.187.93.131:51820
Die öffentliche IP-Adresse (oder DNS-Name) der pfSense plus der verwendete Port.
PersistentKeepalive = 25
Die Einstellung den Tunnel offen zu halten, auch wenn kein Datenverkehr stattfindet.
Die Datei speichert Ihr auf eurem Rechner als .txt oder .conf Datei
Konfigurationsdatei importieren
Auf der FRITZ!Box Oberfläche navigieren wir zu
Internet => Freigaben => VPN (WireGuard)
und klicken dort auf Verbindung hinzufügen:
Wir wählen die 2. Option und Weiter
Wir wählen Ja und Weiter
Wir geben der Verbindung einen Namen (1),
wählen (2) die zuvor erzeugte Datei aus,
aktivieren (3) NetBIOS (steht auch auf dem Prüfstand, wird in vielen anderen Anleitungen so gemacht, habe ich erst einmal so übernommen),
und dann auf Fertigstellen
Ggf. müsst Ihr den Import am Gerät bestätigen (oder per Telefon).
Wen Ihr zurück auf der Übersichtseite seit, sollte die Verbindung dort angezeigt werden, ggf. noch ohne grünen Kreis.
Wenn Ihr auf der pfSense nachseht unter
VPN => WireGuard => Status
ist dort die Verbindung vermutlich schon seit ein einigen Sekunden aktiv:
Und wenn Ihr die Seite auf der FRITZ!Box aktualisiert / einmal hin- und herschaltet ist der Tunnel dort auch aktiv:
Ihr klickt dann einmal auf den Stift (siehe Pfeil) um euch die Details der Verbindung anzeigen zu lassen:
Die FRITZ!Box hat nun auf einem zufälligen Port ihren eigenen WireGuard-Server gestartet, in diesem Fall auf Port 59674
Den Port notieren wir uns für den nächsten Schritt.
Auf der pfSense Teil 3
Abschließend korrigieren wir noch unter
VPN => WireGuard => Peers => angelegter Peer
Den Port auf den von der FRITZ!Box gewählten.
Testen! Testen! Testen!
Das war nun endlich alles.
Testet, pingt hin und her.
Jeder Client aus beiden Netzwerken sollte auf die Ressourcen im jeweils anderen Netzwerk zugreifen können.
Falls sich der Tunnel nicht aufbaut, habt Ihr euch auf einer der Seiten mit den Private Key, Public Key und/oder Shared Key vertan.
Ich hatte da Anfang auch Schlüssel verwechselt (bei den ersten Versuchen hatte ich die WireGuard-Konfig der FritzBox exportiert und diese verwendet).
Wenn etwas mit den Tunneladressen nicht stimmt baut sich der Tunnel selbst aber trotzdem auf.
Steht der Tunnel aber der Zugriff klappt nicht, so prüft ob Ihr die beiden IP-Adressen des Tunnelnetzwerkes anpingen könnt.
Und prüft peinlich genau noch einmal alle Einstellungen, ich habe auch eine Weile gebraucht um ein Komma zu wenig in der Datei für die FRITZ!Box zu finden.
Quellen
- https://docs.netgate.com/pfsense/en/latest/recipes/wireguard-s2s.html
- https://v64.tech/t/anleitung-site2site-wireguard-verbindung-zwischen-pfsense-und-fritzbox/438
- Lösung des NAT-Problems: https://forum.netgate.com/topic/171526/wireguard-fritzbox-pfsense/10