117471
Goto Top

PfSense - Kopplung dreier Netze via OpenVPN

Wer mich kennt weiß, ich lasse nicht locker face-smile

Ich habe die letzten Wochen eingehend damit verbracht, drei Netze über eine pfSense via OpenVPN zu koppeln und möchte die gewonnenen Erfahrungen zum Einen hinterfragen und zum Anderen mit euch teilen.

Dieses Tutorial soll keine reine "Nachklickanleitung" sein. Vielmehr gehe ich auch ein bisschen darauf ein, was ich gemacht habe und warum ich das genau so gemacht habe.


back-to-topZielsetzung


Mein Testnetz besteht aus drei Standorten:
  • horn ist der "Hauptstandort". Hier hänge ich mit einer öffentlichen IP-Adresse an einer Internetfestverbindung
  • farge ist mein Home-Office. Ich befindet mich hinter einer Fritz!Box
  • gamma ist der Hyper-V eines Arbeitskollegen. Hier hänge ich als DHCP-Client an einem Router

Die grundsätzliche Netzwerkkonfiguration lautet:
  • In horn habe ich das Subnetz 10.10.10.0/24. Die pfSense heißt pfHorn und läuft auf einer APU mit der LAN-IP-Adresse 10.10.10.5
  • In farge habe ich das Subnetz 10.10.20.0/24. Die pfSense heißt pfFarge und läuft auf einer APU mit der der LAN-IP-Adresse 10.10.20.5
  • In gamma habe ich das Subnetz 10.10.30./24. Die pfSense heißt pfGamma und läuft in einer Hyper-V VM mit der LAN-IP-Adresse 10.10.30.5

In den Netzen im Home-Office und auf dem Hyper-V betrachte ich mich als "Friendly User". Wichtig war mir, dieses Verhältnis nicht überzustrapazieren und möglichst wenig Abhängigkeiten zur genutzten Infrastruktur zu haben. Auch bin ich so gar kein Freund von diesem ganzen DynDNS-Geraffel und möchte offiziell ausschließlich mit der statischen IP-Adresse am Standort horn sprechen.

Aus diesem Grund habe ich mich entschieden, die Netze via OpenVPN zu koppeln.

Pragmatisch ausgedrückt: Am Hauptstandort horn läuft der VPN-Server, die anderen beiden Netze bauen eigenständig "von innen nach außen" eine Verbindung zum Server auf und koppeln die Netze. Theoretisch könnte ich einen der Domaincontroller und die dazugehörige pfSense im Mai mit nach Ibiza schlörren, an ein LAN anstöpseln und hätte ohne weitere Veränderungen eine vollständige Netzwerkverbindung.

So sieht das aus:

6551199df7a9cba854b5d1ef50adccfa

back-to-topGrundsätzliche Überlegungen


  • Wir müssen uns ein "Transportnetz" für die im VPN verschickten Daten ausdenken. 10.10.100.0/24 drängt sich nahezu auf!
  • Wir möchten Routen auf die VPN-Clients legen. Damit der Server die Clients erkennen kann, bietet es sich an, Zertifikate zu benutzen
  • Der VPN-Server muss wissen, auf welchen Client (anhand des Zertifikates) er welches Netz schicken soll
  • Der VPN-Server muss den Clients (anhand der Zertifikate) mitteilen, welche Netze auf den anderen Clients liegen
  • Am Standort gamma gibt es eine Besonderheit: Die VMs dürfen ausschließlich via Proxy mit dem Internet kommunizieren. Auch wird dort z.B. ntp auf einen eigenen Server umgeleitet, den ich nicht benutzen möchte. Der Standort gamma soll somit sämtlichen Traffic grundsätzlich durch den VPN-Tunnel schicken

back-to-topZertifikate


Ich erstelle sämtliche Zertifikate auf der Server-pfSense am Standort horn.

Grundsätzlich benötigen wir eine Stammzertifizierungsstelle sowie Server- und Userzertifikate, die von dieser Stammzertifizierungsstelle ausgestellt bzw. signiert wurden.

Der Server benötigt mindestens:

  • Das Zertifikat der Stammzertifizierungsstelle
  • Das Serverzertifikat nebst Schlüssel
  • Es bietet sich an, hier auch den Schlüssel für die Stammzertifizierungsstelle und die User-Zertifikate nebst Schlüssel vorzuhalten

Jeder Client benötigt mindestens:

  • Das Zertifikat der Stammzertifizierungsstelle
  • Sein User-Zertifikate nebst Schlüssel

back-to-topDie Stammzertifizierungsstelle

Über System -> Cert Manager rufen wir den Zertifikatsmanager auf und fügen unter dem Reiter CAs eine Stammzertifizierungsstelle hinzu:

pfhorn-ca

pfHorn.varip.de ist übrigens auch der Hostname, den die pfSense LAN-seitig hat. An dieser Stelle muss erwähnt werden, dass Zertifizierungsstellen, Zertifikate usw. ziemlich zickig sein können, wenn die darin angegebenen Hostnamen nicht den tatsächlichen Gegebenheiten im DNS entsprechen. Also - grundsätzlich einmal mehr drüber nachdenken und sorgfältig planen... face-smile

Im Anschluss exportieren wir:

  • pf-Horn-ca.crt

back-to-topServer-Zertifikat

Der VPN-Server auf pfHorn benötigt ein Zertifikat und einen Schlüssel. Dieses erstellen wir ebenfalls über System -> Cert Manager, indem wir dort den Reiter "Certificates" aufrufen. Hier mal ein Beispiel:

pfhorn-servercertificate

Bitte beachten, dass ich unter "Certificate Type" "Server Certificate" ausgewählt habe.

Im Anschluss exportieren wir:

  • nichts face-smile

back-to-topUser-Zertifikate

Jeder Client (auf pfFarge und pfGamma) benötigt ein eigenes Zertifikat und einen dazu passenden Schlüssel. Dieses erstellen wir, indem wir über System -> User-Manager einen neuen Benutzer anlegen. Bei mir sieht das in etwa so aus:

425883e355a904cbb9443b524609326c
3dc3e48e841e86bc952391964dbc3bdb

Ich habe die User der Gruppe "OpenVPN N2N" hinzugefügt. Das ist nicht erforderlich, ich habe es aber ganz gerne ein bisschen strukturierter (Monk!).

Nach dem Anlegen gehen wir noch einmal in die Benutzerverwaltung und exportieren von dort aus:

  • pfFarge.varip.de-pfFarge.varip.de.crt
  • pfFarge.varip.de-pfFarge.varip.de.key

Und weil es so schön war, wiederholen wir das Ganze noch einmal für das User-Zertifikat pfGamma und erhalten somit ebenfalls eine .crt und einen .key

back-to-topEin abschließender Blick in den Cert-Manager von pfHorn

So sieht das bei mir aus:

pfhorn-certmanager

Wie Ihr seht, habe ich zusätzlich neben den User-Zertifikaten für die Außenstandorte pfFarge und pfGamma auch noch ein User-Zertifikat für pfHorn und jka erstellt. Man weiß ja nie, wofür man das noch einmal gebrauchen kann face-smile

Wer den Screenshot jetzt mit seinen Ergebnissen vergleicht wird bemerken, dass in der Zeile für das Serverzertifikat von pfHorn bei "in Use" nichts drin steht. Keine Panik (42!). Sobald das Zertifikat in der VPN-Konfiguration verwurstet ist, wird sich das ändern.

back-to-topImport der gewonnenen Zertifikate auf den Client-Firewalls

Wie bereits mehrfach erwähnt (lehren bedeutet Wiederholung!), benötigt jede Client-Firewall:

  • Das Zertifikat der Stammzertifizierungsstelle
  • Ihr User-Zertifikat und den Schlüssel

Wir rufen also den Cert-Manager auf der Clientfirewall auf und fügen eine neue Zertifizierungsstelle hinzu. Dieses mal generieren wir keine Zertifizierungsstelle, sondern wir importieren deren Zertifikat. Sprich: Wir öffnen die pf-Horn-ca.crt mit einem Texteditor und kopieren deren Inhalt in die dazugehörige Eingabekiste:

627fc82eef769dd8b5c180fe28642476

Den Schlüssel tragen wir nicht ein. Ich habe mir übrigens angewöhnt, einheitliche Namen zu verwenden. Werfen wir noch einmal einen Blick in den Zertifikatsmanager von pfHorn:

pffarge-certmanager

Das "NO" bei "Internal" bedeutet, dass wir die Zertifizierungsstelle zwar benutzen dürfen, aber keine Zertifikate ausstellen können. Und das ist auch gut so - man stelle sich nur mal vor, auf Ibiza wird meine pfSense geklaut - die daraus resultierenden "Nacharbeiten" wären nicht zu unterschätzen face-smile

Wir rufen den Cert-Manager auf der Clientfirewall auf und fügen unter dem Reiter "Certificates" ein neues Zertifikat und dessen Schlüssel hinzu. Das Zertifikat wird ebenfalls mit Copy & Paste aus der pfFarge.varip.de-pfFarge.varip.de.crt bezogen, den Schlüssel hatten wir ja in die pfFarge.varip.de-pfFarge.varip.de.key gespeichert.

85b8b67e5fb3c0501e73f20d83411ae0

back-to-topNAT (=NAT rules!^^)


Jede pfSense hat so genannte NAT-Regeln. Salopp gesagt beschreiben die NAT-Regeln, welche Quellnetze auf welche Schnittstelle geschickt werden. Auch hier wieder ein paar Überlegungen vorab:

  • Jede Firewall schickt ihren eigenen Traffic ins Internet (also alles, was von 127.0.0.0/8 kommt)
  • Jede Firewall schickt den Traffic aus ihrem eigenen Netz ins Internet
  • Jede Firewall schickt den Traffic aus dem OpenVPN-Transportnetz (10.10.100.0/24) ins Internet
  • Da wir den gesamten Datenverkehr von pfGamma durch den Netzwerktunnel schieben, schickt die Server-Firewall pfHorn auch Datenpakete aus deren lokalen Netz ins Internet

Die NAT-Regeln finden wir unter Firewall -> NAT auf dem Reiter "Outbound". Da wir grundsätzlich alles besser wissen, setzen wir den Radioknopf "Manual Outbound NAT rule generation (AON - Advanced Outbound NAT)" und klicken einmal beherzt auf Speichern. Danach erstellen wir das Regelwerk. Hier ein Bildschirmfoto von der Server-Firewall pfHorn:

9cd580b9cde57468adcbf54057e589fa

Ihr seht, dass es für jedes ausgehende Mapping zwei Pendants gibt (eine Regel für den statischen Port 500, eien Regel für "alles"). Kleiner Tipp: Ihr könnt eine vorhandene Regel als Vorlage benutzen, indem Ihr neben der Regel auf den Button mit dem e klickt).

Wir erinnern uns an unsere Strategie:

  • Am Server-Standort horn funktioniert die pfSense als klassiches Gateway. Also gehen wir dort erst einmal mit dem Netz von horn und dem OpenVPN-Transportnetz raus
  • Am Standort farge werden nur die Datenpakete für die Netze in horn und gamma in den VPN-Tunnel gesteuert. Diese werden innerhalb unserer eigenen Struktur terminiert und müssen daher nicht(!) genattet werden. Darum gibt es hier kein Mapping für 10.10.20.0/24
  • Am Standort gamma wird der gesamte Datenverkehr in den VPN-Tunnel geschickt. Das können auch Datenpakete für das Internet sein. Darum gibt es hier das Mapping für 10.10.30.0/24

Das ist wie gesagt der Server pfHorn. Noch einmal zur Wiederholung:

  • Der Server schickt seinen gesamten "internen" Datenverkehr (DNS-Abfragen, NTP-Abfragen usw.) ins Internet.
  • Der Server schickt alles aus seinem eigenen LAN ins Internet
  • Der Server schickt alles aus dem Netz von pfGamma (das ist das Netz, dass via VPN reinkommt komplett ins Internet geroutet werden soll) ins Internet
  • Der Server schickt alles aus dem VPN-Transportnetz (10.10.100.0/24) ins Internet

Aus Gründen der Vollständigkeit zeige ich hier die Mappings der anderen beiden Firewalls:

8603d4aebb951be04ac2dca788806b49
07e578975681b7b7dc04dc8e01a8413c

back-to-topFirewall-Regeln


Die Netze zu verbinden ist eine Sache. Wichtig ist natürlich auch, dass die Netze miteinander sprechen (dürfen). Unter Firewall -> Rules wird unter dem Reiter "OpenVPN" festgelegt, wer was darf. Hier meine Regel:

26d06e66c160b9433060238cf6bb248a

Deren Bedeutung: "Alles, was über OpenVPN geht ist netzwerktechnisch vertrauenswürdig und darf alles, was die Computer im jeweiligen LAN dürfen". Eine derartige Regel gibt es natürlich auf allen drei Firewalls.

Hier noch einmal die Regel im Detail:

e3982317bf0e7a572da334abb9a6ae2d

Der OpenVPN-Server hört auf Port 1194 (UDP) und muss von aussen erreichbar sein. Die dazugehörige Regel definieren wir unter Firewall -> Rules, dieses Mal unter dem Reiter "WAN":

b73d43546ba742870da0aeb80d376c4f

Auch diese Regel vermag ich noch einmal detailliert aufzuzeigen:

d2c4336d3bdecff400ebc7238013f091

back-to-topVPN-Konfiguration


back-to-topVPN-Server

Im Menü VPN -> OpenVPN fügen wir unter dem Reiter "Server" einen neuen Server hinzu:

a6315bc55aac7460177b5dca8cbc6469
33694736bb005986dfb92f3c52542e43

Bitte ein paar Details beachten:
  • "Server Mode" ist "Peer to Peer (SSL/TLS)"
  • "Local Port" und "Protocol" entspricht unserer Firewall-Regel (1194 UDP)
  • "Peer Certificate Authority" zeigt auf die Stammzertifizierungsstelle
  • "Server Certificate" zeigt auf das Server-Zertifikat
  • "IPv4 Tunnel Network" beinhaltet das Tunnelnetz (siehe NAT-rules)
  • "IPv4 Remote Network/s" beinhaltet die Netze der Client-Firewalls, getrennt durch ein Komma

Nachdem wir den Tunnel hinzugefügt haben, sieht das Ganze dann so aus:

5d81e1cc82973bf52eaf2103711f8dc7

Wie benötigen den TLS-Key für die Clients. Also klicken wir neben dem jüngst geschaffenen VPN-Server noch einmal auf den Edit-Button.

7a91454020d66ca9feb77d36acab6f9a

Den vollständigen Inhalt des Feldes "TLS Authentication" kopieren wir in die Zwischenablage und speichern ihn in einer Textdatei.

Damit weiß der OpenVPN-Server grundsätzlich, welche Netze er ins OpenVPN routen soll. Aber woher soll er wissen, auf welchem der Clients er das Netz finden soll?

Wir gehen noch einmal in das Menü VPN -> OpenVPN und widmen uns dem Reiter "Client Specific Overrides". Für die beiden Firewall in farge und gamma fügen wir eine clientspezifische Konfiguration hinzu. Zuerst die pfSense in farge:

a0cd5587a4c05711ade3a35d9b74eab5
587dca9caac69cfeb86c4201ff4f2166

Auch hier wieder die bewährte Zusammenfassung der relevanten Informationen:

  • "Common Name" ist der Name des Zertifikates (siehe oben!). Bitte minutiös eingeben (ich hatte da versehentlich ein Leerzeichen am Ende...)
  • "Tunnel Network" ist unser Tunnelnetz (siehe NAT-rules und Konfiguration des OpenVPN-Servers)
  • "IPv4 Remote Network/s" sind die Netze, die der OpenVPN-Server in farge findet
  • "Advanced": Der ifconfig-push Befehl gibt dem Server und dem Client für genau diese Verbindung jeweils eine statische IP-Adresse im Tunnel
  • "Advanced": Der push-Befehl sagt dem Client nach dem Verbindungsaufbau, welche Netze er über den OpenVPN-Server erreichen kann. In diesem Fall pfHorn zu pfFarge: "Hey - das Netz von pfGamma findest Du übrigens über mich"

Eine Anmerkung zu den statischen IP-Adressen im Tunnel (ifconfig-push): Diese Adressen müssen zusammenpassen. Dazu ein passendes Zitat aus der OpenVPN-Howto:
Specifically, the last octet in the IP address of each endpoint pair must be taken from this set:

[ 1, 2] [ 5, 6] [ 9, 10] [ 13, 14] [ 17, 18]
[ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] [ 37, 38]
[ 41, 42] [ 45, 46] [ 49, 50] [ 53, 54] [ 57, 58]
[ 61, 62] [ 65, 66] [ 69, 70] [ 73, 74] [ 77, 78]
[ 81, 82] [ 85, 86] [ 89, 90] [ 93, 94] [ 97, 98]
[101,102] [105,106] [109,110] [113,114] [117,118]
[121,122] [125,126] [129,130] [133,134] [137,138]
[141,142] [145,146] [149,150] [153,154] [157,158]
[161,162] [165,166] [169,170] [173,174] [177,178]
[181,182] [185,186] [189,190] [193,194] [197,198]
[201,202] [205,206] [209,210] [213,214] [217,218]
[221,222] [225,226] [229,230] [233,234] [237,238]
[241,242] [245,246] [249,250] [253,254]

Die Clientspezifische Konfiguration für gamma unterscheidet sich in einigen Punkten:

2c5fa199a104e674fe23fdc3aae39078
dfd12dfcbca0ed1e7ca800ccc910f3dc

  • "Common Name" ist der Name des Zertifikates
  • "Tunnel Network" ist unser Tunnelnetz (siehe NAT-rules und Konfiguration des OpenVPN-Servers)
  • "IPv4 Remote Network/s" sind die Netze, die der OpenVPN-Server in gamma findet
  • "Redirect Gateway": Wir erinnern uns - in gamma gibt es den Proxy-Server, den wir nicht benutzen möchten. Also schicken wir von dort aus den gesamten Traffic in das VPN
  • "Advanced": Der ifconfig-push Befehl gibt dem Server und dem Client für genau diese Verbindung jeweils eine statische IP-Adresse im Tunnel. Das ist ein anderes Adresspaar als in der clientspezifischen Konfiguration von pfHorn...(!!!)
  • "Advanced": Der push-Befehl sagt dem Client nach dem Verbindungsaufbau, welche Netze er über den OpenVPN-Server erreichen kann. In diesem Fall pfHorn zu pfGamma: "Hey - das Netz von pfFarge findest Du übrigens über mich"

back-to-topVPN-Client

Auch wenn der Client-Dialog auf pfFarge und pfGamma etwas länger ist, soll uns das nicht abschrecken. Im Gegenteil - da wir uns gedanklich an unsere Beispielkonfiguration gewöhnt haben und diese gepflegt auswendig kennen, beschränkt sich das auf ein reines Eintippen der Informationen face-smile

32356ed7642d17a019b0ac5be8e88675
4347488e4d29edf11672e4a23d8814d6
6079ac85b79b9eeb6438f737b74b814a
248e0796944cbf589635c3827338b8ff

Wichtige Informationen:

  • "Server Mode" ist "Peer to Peer (SSL/TLS)"
  • "Server port" und "Protocol" ist wieder 1194 (UDP), vergleiche u.A. die Filterregel und die OpenVPN-Konfiguration auf der Server-Firewall
  • "Server host or address" ist der externe Name der Server-Sense in horn. Dies kann eine IP-Adresse oder ein Hostname sein
  • "User Authentication Settings" lassen wir leer(!). Hier werden auch nicht die Daten eingetragen, die wir beim Ersteller der User-Zertifikate eingetragen haben!
  • "User Name/pass" lassen wir leer - auch wenn wir beim Anlegen des Benutzers ursprünglich Zugangsdaten festgelegt haben...
  • "TLS Authentication": Den Schlüssel haben wir erhalten, als wir auf der Serverfirewall noch einmal das eingerichtete Profil editiert haben. Dieser wird hier mit Copy & Paste eingefügt
  • "Peer Certificate Authority" ist die Stammzertifizierungsstelle, die wir hier importiert hatten
  • "Client Certificate" haben wir auf der pfHorn über den "User Manager" expor- und hier importiert
  • "IPv4 Tunnel Network" kennen wir ebenfalls zur Genüge (unser Transportnetz...)
  • "IPv4 Remote Networks" ist *nur* das Netzwerk auf der Server-Firewall pfHorn. Verlockend wäre "eigentlich", hier auch noch das Netzwerk in gamma einzutragen. Aaaaber - diese Information bekommen wir ja über die clientspezifische Konfiguration gepusht... face-smile

back-to-topStatus


Wenn wir unter Services -> OpenVPN den Status aufrufen, bekommen wir nicht nur den Verbindungsstatus angezeigt. Mit der Schaltfläche darunter erhalten wir nach einer gewissen Kalkulationszeit die Routing-Tabelle angezeigt.

pfhorn-status

Wie wir hier sehen können, haben bereits einige Hosts Verbindung über den VPN-Tunnel aufgenommen. Diese Verbindungen werden mit C angezeigt.

Content-Key: 298055

Url: https://administrator.de/contentid/298055

Printed on: April 18, 2024 at 03:04 o'clock