OPNsense HA Umsetzung: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(18 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== Plan ==
+
=Plan=
 
+
{{#drawio:ha-opnsense-kit}}
{{#drawio:OPNsense Multiwan}}
 
<!-- Grafik neu zeichnen: die Adressen im Bild (192.168.4.0/24, 172.30.34.0/24)
 
    stimmen nicht mit der Konfiguration überein. -->
 
  
 +
== Platzhalter in diesem Artikel ==
 
{| class="wikitable"
 
{| class="wikitable"
! Rolle !! Interface !! Gerät !! Identifier !! IP-Adresse !! Provider-Gateway
+
! Platzhalter !! Bedeutung !! Beispiel
|-
 
| Internes Netz || LAN || em0 || lan || ''LAN-Netz''/24 || –
 
 
|-
 
|-
| Provider A || WAN1 || em1 || opt2 || 192.168.HS.2XX/24 || 192.168.HS.254
+
| '''HS''' || Drittes Oktett des Schulungsnetzes (WAN), wird vom Trainer vorgegeben || 4
 
|-
 
|-
| Provider B || WAN2 || em4 || opt4 || 172.30.34.2XX/24 || 172.30.34.254
+
| '''X''' || Deine Teilnehmernummer, wird vom Trainer vorgegeben || 13
 
|}
 
|}
  
''Hinweis: Die Identifier (opt1, opt2, opt3 …) vergibt OPNsense in der Reihenfolge, in der die
+
* Beispiel für X=13 und HS=4: WAN Master 192.168.4.53, WAN Backup 192.168.4.73, WAN-VIP 192.168.4.33, VHID 13
Interfaces angelegt werden. Sie müssen nicht fortlaufend zu den Gerätenamen passen – wichtig ist
+
* '''Alle Passwörter in diesem Artikel sind Laborwerte und dürfen so niemals in eine produktive Umgebung übernommen werden.'''
nur, dass sie in Gateways, DNS und Regeln konsistent referenziert werden.''
 
 
 
''In dieser Umsetzung ist '''WAN2 die primäre Leitung''' (Tier 1). WAN1 dient als Backup (Tier 2).''
 
  
== Was müssen wir tun? ==
+
=Wichtig=
 +
* Die Netzwerkkarten für LAN und WAN müssen '''im Hypervisor''' in den Promiscuous-Modus geschaltet werden – nicht in OPNsense.
 +
** VirtualBox: Maschine => Ändern => Netzwerk => Adapter => Erweitert => Promiscuous-Modus: '''Alle erlauben'''
 +
** Proxmox: Bridge ohne MAC-Filter bzw. entsprechende Bridge-Einstellung
 +
* Das gilt sowohl für den Master als auch für das Backup.
  
* 2 WAN-Interfaces anlegen
+
;Begründung
* 2 Gateways definieren
+
* CARP verwendet virtuelle MAC-Adressen für die gemeinsame VIP. In virtualisierten Umgebungen werden Frames mit diesen MAC-Adressen vom Hypervisor standardmäßig verworfen, da sie nicht der echten VM-NIC zugeordnet sind. Ohne aktivierten Promiscuous-Modus erreichen CARP-Advertisements den Partner nicht, was zu Fehldetektion, unerwünschtem Failover und HA-Inkonsistenzen führt.
* Eine Gatewaygruppe erstellen
 
* Die Internetleitungen überwachen (Healthcheck über Monitor-IP)
 
* Eine Entscheidungsinstanz schaffen: die Gatewaygruppe entscheidet über Tier und Trigger Level
 
* Zuordnung klären: Policy Routing über die Gateway-Angabe in der Firewallregel
 
* DNS-Server pro Leitung zuordnen
 
* Firewallregeln anpassen (Reihenfolge beachten!)
 
* NAT-Regeln anpassen
 
* Szenarien testen
 
  
== Konfiguration ==
+
= Vorbereitung =
 +
* Zwei OPNsense-Installationen mit jeweils mind. 3 Netzwerkkarten
 +
* Auf beiden Maschinen muss die '''gleiche OPNsense-Version''' laufen
 +
* Die Anzahl der Netzwerkkarten muss auf beiden Maschinen gleich sein
 +
* '''Die Reihenfolge und Anzahl der Netzwerkschnittstellen muss auf beiden Maschinen identisch sein!'''
 +
* Empfehlung für beide Maschinen:
 +
** em0: LAN
 +
** em1: WAN
 +
** em2: SYN
 +
* Am Anfang sollten so wenige Dienste wie möglich laufen
 +
== opnsense-template klonen ==
 +
* Beim Klonen '''"Neue MAC-Adressen für alle Netzwerkkarten erzeugen"''' auswählen
  
=== Interface WAN1 ===
+
== IP-Adressen der Backup Firewall ==
 +
;Template klonen als opns-ha2
 +
====System-Settings: General====
 +
*Hostname: opns-ha2
 +
*Theme: opnsense-dark
 +
* Gateway anlegen: 192.168.HS.254 und später WAN zuordnen
 +
* em0 (LAN): 192.168.1.2/24
 +
* em1 (WAN): 192.168.HS.X+60/24
 +
* em2 (SYN): 100.64.64.2/30
  
''Interfaces: [WAN1]''
+
== IP-Adressen der Master Firewall ==
 +
;Template klonen als opns-ha1
 +
====System-Settings: General====
 +
*Hostname: opns-ha1
 +
*Theme: opnsense
 +
* Gateway anlegen: 192.168.HS.254 und später WAN zuordnen
 +
* em0 (LAN): 192.168.1.1/24 (bereits aus dem Template)
 +
* em1 (WAN): 192.168.HS.X+40/24
 +
* em2 (SYN): 100.64.64.1/30
  
 +
== Übersicht ==
 
{| class="wikitable"
 
{| class="wikitable"
! Feld !! Wert
+
! !! Master (opns-ha1) !! Backup (opns-ha2) !! VIP !! VHID
 
|-
 
|-
| Enable || aktiv
+
| LAN (em0) || 192.168.1.1 || 192.168.1.2 || 192.168.1.3 || 100
 
|-
 
|-
| Device || em1
+
| WAN (em1) || 192.168.HS.X+40 || 192.168.HS.X+60 || 192.168.HS.X+20 || X
 
|-
 
|-
| Description || WAN1
+
| SYN (em2) || 100.64.64.1 || 100.64.64.2 || – || –
 +
|}
 +
 
 +
* Die VHID muss nur innerhalb einer Broadcast-Domäne eindeutig sein, der Wertebereich ist 1 bis 255.
 +
* Da sich alle Teilnehmer das WAN-Segment teilen, wird dort die Teilnehmernummer X verwendet (1 bis 13).
 +
* Das LAN ist pro Teilnehmer ein eigenes, isoliertes Segment. Dort steht deshalb bei allen Teilnehmern fest die 100. Der Abstand zum WAN-Bereich ist Absicht: dreistellig = LAN, zweistellig = WAN.
 +
 
 +
= Firewall Regeln (beide Firewalls) =
 +
* Auf dem '''WAN'''-Interface muss das Protokoll CARP akzeptiert werden
 +
* Dazu im Menü '''Firewall => Rules => WAN''' eine Allow-Regel erstellen, die auf das CARP-Protokoll matcht
 +
* Auf dem '''LAN'''-Interface genügt die Default-Regel "Default allow LAN to any" – sie erlaubt jedes Protokoll
 +
** Wird diese Regel später durch restriktive Regeln ersetzt, muss dort eine eigene CARP-Regel ergänzt werden, sonst bricht der Cluster im LAN auseinander
 +
* Für das SYN-Interface eine Standard-Allow-Regel erstellen, die alles erlaubt
 +
 
 +
= Virtuelle IPs (Master Firewall) =
 +
* Die virtuellen IPs werden von den Knoten des HA-Clusters geteilt, sobald ein Ausfall erkannt wird
 +
* Somit wird dafür gesorgt, dass die virtuelle IP immer erreichbar ist
 +
* Die virtuelle IP wird '''nur''' auf der Master Firewall eingestellt und an die Backups mitgeteilt
 +
* Dazu muss man im Menü '''Interfaces => Virtual IPs => Settings''' an allen Schnittstellen bis auf das SYN-Interface die gewünschten IPs vergeben
 +
* Über das '''[+]''' auf der rechten Seite muss man folgende Einträge machen:
 +
 
 +
== virtuelle WAN IP ==
 +
{| class="wikitable"
 +
! Parameter !! Wert
 +
|-
 +
| Mode || CARP
 
|-
 
|-
| Block private networks || aus
+
| Interface || WAN
 
|-
 
|-
| Block bogon networks || aus
+
| Address || 192.168.HS.X+20/24
 
|-
 
|-
| IPv4 Configuration Type || Static IPv4
+
| Virtual Password || radler
 
|-
 
|-
| IPv6 Configuration Type || None
+
| VHID Group || X
 
|-
 
|-
| IPv4 address || 192.168.HS.2XX/24
+
| Advertising Frequency || 1
 
|-
 
|-
| IPv4 Upstream Gateway || WAN1GW
+
| Description || Virtual WAN IP
 
|}
 
|}
  
'''Wichtig:''' Die Präfixlänge <code>/24</code> darf nicht fehlen, sonst wird das Interface mit /32
+
== virtuelle LAN IP ==
angelegt und das Gateway ist nicht erreichbar.
 
 
 
=== Interface WAN2 ===
 
 
 
''Interfaces: [WAN2]''
 
 
 
 
{| class="wikitable"
 
{| class="wikitable"
! Feld !! Wert
+
! Parameter !! Wert
 
|-
 
|-
| Enable || aktiv
+
| Mode || CARP
 
|-
 
|-
| Device || em4
+
| Interface || LAN
 
|-
 
|-
| Description || WAN2
+
| Address || 192.168.1.3/24
 
|-
 
|-
| Block private networks || aus
+
| Virtual Password || radler
 
|-
 
|-
| Block bogon networks || aus
+
| VHID Group || 100
 
|-
 
|-
| IPv4 Configuration Type || Static IPv4
+
| Advertising Frequency || 1
 
|-
 
|-
| IPv6 Configuration Type || None
+
| Description || Virtual LAN IP
 +
|}
 +
 
 +
= Source NAT (Master Firewall) =
 +
* Da die virtuelle IP für ausgehende Verbindungen benutzt werden soll, muss die automatische Regelgenerierung ausgeschaltet werden
 +
* Im Menü '''Firewall => NAT => SNAT''' den Modus auf '''Manual''' stellen
 +
* Dann die folgende Regel erstellen:
 +
{| class="wikitable"
 +
! Parameter !! Wert
 +
|-
 +
| Interface || WAN
 
|-
 
|-
| IPv4 address || 172.30.34.2XX/24
+
| Source || LAN network
 
|-
 
|-
| IPv4 Upstream Gateway || WAN2GW
+
| Translate Source IP || Virtual WAN IP (192.168.HS.X+20)
 
|}
 
|}
  
=== Einstellen der Gateways ===
+
= High Availability Konfiguration (Master Firewall) =
 
+
* Die eigentliche HA-Einstellung erfolgt über das Menü '''System => High Availability => Settings''':
''System: Gateways: Configuration''
 
 
 
 
{| class="wikitable"
 
{| class="wikitable"
! Feld !! GW1 !! GW2
+
! Parameter !! Wert
 
|-
 
|-
| Name || WAN1GW || WAN2GW
+
| Synchronize all states via || SYN
 
|-
 
|-
| Interface || WAN1 || WAN2
+
| Sync compatibility || OPNsense 24.7 or above
 
|-
 
|-
| Address Family || IPv4 || IPv4
+
| Synchronize Peer IP || 100.64.64.2
 
|-
 
|-
| IP Address || 192.168.HS.254 || 172.30.34.254
+
| Synchronize Config || 100.64.64.2
 
|-
 
|-
| Upstream Gateway || '''aktiv''' || '''aktiv'''
+
| Verify peer || deaktiviert
 
|-
 
|-
| Far Gateway || aus || aus
+
| Remote System Username || root
 
|-
 
|-
| Disable Gateway Monitoring || aus || aus
+
| Remote System Password || radler
 
|-
 
|-
| Monitor IP || 9.9.9.9 || 208.67.222.222
+
| Services || Aliases, Firewall Rules, NAT, Virtual IPs
|-
 
| Priority || 255 || 254
 
 
|}
 
|}
  
Drei Punkte, die häufig falsch gemacht werden:
+
* "Verify peer" bleibt deaktiviert, weil die Web-GUI der Gegenstelle ein selbstsigniertes Zertifikat verwendet.
 
 
* '''Upstream Gateway''' muss bei ''beiden'' Gateways gesetzt sein. Es kennzeichnet ein Gateway als
 
  Internet-Ausgang; ist es nur bei einem gesetzt, verhält sich das Failover unvorhersehbar.
 
* Die '''Monitor-IPs müssen bei verschiedenen Betreibern liegen''' und dürfen nicht mit den
 
  DNS-Servern identisch sein. 8.8.8.8 und 8.8.4.4 gehören beide Google: fällt Google aus, werden
 
  beide Leitungen als tot gemeldet. Für jede Monitor-IP legt OPNsense zusätzlich eine Hostroute über
 
  das jeweilige Gateway an; benutzt man dieselbe IP auch als DNS-Server, überlagern sich Hostroute
 
  und DNS-Zuordnung.
 
* Die niedrigere '''Priority''' gewinnt bei der Wahl des '''Default-Gateways'''. Das Default-Gateway
 
  bestimmt den Ausgang für den Eigenverkehr der Firewall (Updates, NTP, rekursiver Resolver) – es ist
 
  unabhängig von der Gatewaygruppe. Damit die primäre Leitung WAN2 auch das Default-Gateway stellt,
 
  bekommt '''WAN2GW die niedrigere Priority (254)''' und WAN1GW die höhere (255). Stünden beide gleich,
 
  wäre die Wahl zufällig.
 
 
 
=== Einstellen der Gatewaygruppe ===
 
 
 
''System: Gateways: Group''
 
  
 +
= High Availability Konfiguration (Backup Firewall) =
 +
* Hier darf im Menü '''System => High Availability => Settings''' nur folgendes eingestellt werden:
 
{| class="wikitable"
 
{| class="wikitable"
! Feld !! Wert
+
! Parameter !! Wert
 +
|-
 +
| Synchronize all states via || SYN
 
|-
 
|-
| Group Name || GW_GROUP
+
| Sync compatibility || OPNsense 24.7 or above
 
|-
 
|-
| Gateway Priority || WAN2GW = Tier 1, WAN1GW = Tier 2
+
| Synchronize Peer IP || 100.64.64.1
 
|-
 
|-
| Trigger Level || '''Member Down'''
+
| Synchronize Config || leer
 
|-
 
|-
| Pool Options || Default
+
| Verify peer || deaktiviert
|}
+
|-
 
+
| Remote System Username || leer
{| class="wikitable"
 
! Ziel !! Tier-Vergabe !! Trigger Level
 
 
|-
 
|-
| Failover (Standard hier) || WAN2GW = Tier 1, WAN1GW = Tier 2 || Member Down
+
| Remote System Password || leer
 
|-
 
|-
| Lastverteilung || beide Tier 1 || Packet Loss or High Latency
+
| Services || Nothing selected
 
|}
 
|}
  
''Bei Lastverteilung zusätzlich'' ''Firewall: Settings: Advanced'' → ''Sticky connections''
+
* '''Synchronize Config''' muss auf dem Backup leer bleiben. Trägt man hier den Master ein, schieben sich beide Knoten gegenseitig ihre Konfiguration zu.
''aktivieren, sonst wechseln einzelne Verbindungen desselben Clients die Leitung.''
 
  
'''Merke:''' Tier steuert das Failover des '''Client-Verkehrs''' (über die Firewallregel mit
+
= Client im LAN =
GW_GROUP). Die Priority steuert das '''Default-Gateway''' (Eigenverkehr der Firewall). Beide müssen
+
* Der Windows-Client (192.168.1.50) muss als '''Gateway''' und als '''DNS-Server''' die LAN-VIP '''192.168.1.3''' erhalten – nicht die 192.168.1.1
zusammenpassen – sonst laufen Nutzverkehr und DNS über verschiedene Leitungen, und das Verhalten wirkt
+
* Wird die echte IP des Masters eingetragen, ist der Client beim Ausfall des Masters trotz funktionierendem Cluster offline
widersprüchlich.
+
* Bei Verwendung eines DHCP-Servers muss dieser die VIP als Gateway und DNS verteilen
 
 
=== DNS pro Leitung ===
 
 
 
''System: Settings: General''
 
  
 +
= Endergebnis =
 +
==Master==
 +
* System
 +
** High Availability
 +
*** Status
 +
* Hier müssen beide Spalten gefüllt sein und auf beiden Knoten die gleichen Dienste erscheinen:
 
{| class="wikitable"
 
{| class="wikitable"
! DNS Server !! Use gateway
+
! Service !! Description
 +
|-
 +
| configd || Configd
 
|-
 
|-
| 8.8.8.8 || WAN1GW
+
| cron || Cron
 
|-
 
|-
| 1.1.1.1 || WAN2GW
+
| hostwatch || Hostwatch
|}
+
|-
 
+
| login || Users and Groups
* ''Prefer IPv4 over IPv6'': aktiv
+
|-
* Die Zuordnung sorgt dafür, dass jeder DNS-Server über „seine“ Leitung befragt wird. Fällt eine
+
| ntpd || Ntpd
  Leitung aus, bleibt der andere Resolver erreichbar.
+
|-
* '''Voraussetzung:''' Die „Use gateway“-Zuordnung greift nur, wenn Unbound im '''Forwarding-Modus'''
+
| openssh || Secure Shell
  läuft (''Services: Unbound DNS: General'' → ''Enable Forwarding Mode''). Im Standard-Resolving-Modus
 
  löst Unbound rekursiv selbst auf und geht dabei über das Default-Gateway – dann ist die Zuordnung
 
  wirkungslos.
 
 
 
=== NAT auf beiden WAN-Interfaces ===
 
 
 
''Firewall: NAT: Outbound'' – manuelle Regeln (Protokoll und Ports jeweils <code>*</code>, IPv4)
 
 
 
{| class="wikitable"
 
! # !! Interface !! Source !! Destination !! Translate / target !! Beschreibung
 
 
|-
 
|-
| 1 || WAN1 || LAN network || * || Interface address || LAN ins Internet
+
| pf || Packet Filter
 
|-
 
|-
| 2 || WAN1 || SERVER network || * || Interface address || SERVER ins Internet
+
| routing || System routing
 
|-
 
|-
| 3 || WAN1 || DMZ network || <code>! 10.88.0.0/16</code> || Interface address || DMZ ins Internet – kein NAT zu den anderen DMZs
+
| sysctl || System tunables
 
|-
 
|-
| 4 || WAN2 || LAN network || * || Interface address || LAN ins Internet
+
| syslog-ng || Syslog-ng
 
|-
 
|-
| 5 || WAN2 || SERVER network || * || Interface address || SERVER ins Internet
+
| unbound || Unbound DNS
 
|-
 
|-
| 6 || WAN2 || DMZ network || <code>! 10.88.0.0/16</code> || Interface address || DMZ ins Internet – kein NAT zu den anderen DMZs
+
| webgui || Web GUI
 
|}
 
|}
 +
;Wichtig:
 +
  '''Syncronize and reconfigure all'''
  
Das Ausrufezeichen vor dem Zielnetz invertiert die Bedingung: Die Regel greift für alle Ziele
+
==Slave==
'''außer''' <code>10.88.0.0/16</code>. Verkehr aus der DMZ zu den übrigen internen Netzen wird
+
* System
also nicht übersetzt und behält seine Quelladresse – nur so bleiben Logs und Firewallregeln
+
** High Availability
auf den Zielsystemen auswertbar.
+
*** Status
 +
* Auf der Backup-Firewall erscheint hier die Warnung, dass die XMLRPC-Konfiguration unvollständig sei.
 +
* Diese Meldung kann ignoriert werden: Das Backup empfängt nur passiv, deshalb sind die XMLRPC-Felder dort absichtlich leer und werden fälschlicherweise als "unvollständig" markiert. Solange die Master-Firewall auf Version 24.7 eingestellt ist und die Daten erfolgreich überträgt, arbeitet der Cluster technisch einwandfrei.
  
''Jede Regel existiert doppelt, einmal je WAN-Interface. Das ist bei Multiwan zwingend: Welche
+
= Failover testen =
Leitung genutzt wird, entscheidet das Policy Routing der Firewallregel; die passende NAT-Regel
+
* Auf dem Client einen Dauerping nach draußen starten:
muss auf beiden Wegen bereitstehen.''
+
ping -t 192.168.HS.254
 +
* Auf dem '''Master''': Interfaces => Virtual IPs => Status => '''Enter Persistent CARP Maintenance Mode'''
 +
* Erwartetes Verhalten:
 +
** Das Backup wechselt für beide VHIDs von BACKUP auf MASTER
 +
** Der Ping läuft weiter oder verliert maximal ein bis zwei Pakete
 +
* Kontrolle auf beiden Knoten:
 +
ifconfig em0 ; ifconfig em1
 +
* Zurückschalten über '''Leave Persistent CARP Maintenance Mode''' auf dem Master
 +
* Zweiter Test: Master hart ausschalten (VM stoppen) und das gleiche Verhalten prüfen
  
=== Firewallregeln mit Gateway-Gruppe ===
+
=Debugging=
  
''Firewall: Rules: LAN'' '''die Reihenfolge ist entscheidend:'''
+
== Vorgehen ==
 +
* Von unten nach oben prüfen: erst CARP (Layer 2/3), dann pfsync (States), dann XMLRPC (Konfiguration)
 +
* Ein Cluster kann sauber synchronisieren und trotzdem kein Failover können und umgekehrt
  
 +
== Schritt 1: CARP-Status ==
 +
* Auf beiden Knoten:
 +
ifconfig em0 ; ifconfig em1
 +
* Erwartetes Bild:
 
{| class="wikitable"
 
{| class="wikitable"
! # !! Action !! Source !! Destination !! Gateway !! Zweck
+
! Knoten !! LAN (vhid 100) !! WAN (vhid X)
 
|-
 
|-
| 1 || Pass || LAN net || This Firewall || ''leer (default)'' || DNS, NTP, Web-GUI
+
| Master || MASTER, advskew 0 || MASTER, advskew 0
 
|-
 
|-
| 2 || Pass || LAN net || Alias LOKALE_NETZE || ''leer (default)'' || interne Netze, DMZ, VPN
+
| Backup || BACKUP, advskew 100 || BACKUP, advskew 100
|-
 
| 3 || Pass || LAN net || any || '''GW_GROUP''' || Internetverkehr über die Gruppe
 
 
|}
 
|}
 +
* In der GUI: '''Interfaces => Virtual IPs => Status'''
 +
* CARP global ein-/ausgeschaltet:
 +
sysctl net.inet.carp.allow
 +
* Ausführlichere CARP-Meldungen im Log einschalten:
 +
sysctl net.inet.carp.log=2
  
Regel 3 im Detail:
+
== Schritt 2: Beide Knoten sind MASTER (Split Brain) ==
 
+
* Das häufigste Fehlerbild im Labor. Beide Knoten sehen den Partner nicht und übernehmen die VIP.
 +
* Prüfen, ob die Advertisements des Partners überhaupt ankommen:
 +
tcpdump -n -i em1 proto 112
 +
tcpdump -n -i em0 proto 112
 +
* Man muss die Pakete '''beider''' Knoten sehen (Quelle = jeweils die echte Interface-IP)
 
{| class="wikitable"
 
{| class="wikitable"
! Feld !! Wert
+
! Beobachtung !! Ursache
|-
 
| Action || Pass
 
|-
 
| Quick || aktiv
 
|-
 
| Interface || LAN
 
|-
 
| Direction || in
 
|-
 
| TCP/IP Version || IPv4
 
|-
 
| Protocol || any
 
 
|-
 
|-
| Source || LAN net
+
| Nur eigene Pakete sichtbar || Promiscuous-Modus im Hypervisor fehlt
 
|-
 
|-
| Destination || any
+
| Gar keine Pakete sichtbar || VIP nicht angelegt oder Interface down
 
|-
 
|-
| Description || LAN to any über Gateway-Gruppe
+
| Pakete kommen an, trotzdem beide MASTER || CARP-Allow-Regel auf dem Interface fehlt
 
|-
 
|-
| Gateway || GW_GROUP
+
| Pakete mit fremder VHID || Anderer Teilnehmer nutzt die gleiche VHID
 
|}
 
|}
 +
* Weitere Ursachen bei Split Brain:
 +
** Unterschiedliches '''Virtual Password''' auf den beiden Knoten
 +
** Unterschiedliche '''VHID''' auf den beiden Knoten
 +
** Unterschiedliche '''Advertising Frequency'''
  
'''Der klassische Fehler:''' Nur eine einzige Regel mit Gateway GW_GROUP. Eine Gateway-Angabe
+
== Schritt 3: Kein Failover trotz korrektem Status ==
erzwingt Policy Routing für ''alles'', was auf die Regel passt – auch für Pakete an die DMZ, an
+
* Demotion-Zähler prüfen – ist er größer als 0, bleibt der Knoten absichtlich BACKUP:
VPN-Gegenstellen und an die Firewall selbst. Diese Pakete werden dann in Richtung Internet
+
sysctl net.inet.carp.demotion
geschickt und verschwinden. Deshalb müssen die Regeln 1 und 2 ''ohne'' Gateway-Angabe darüber
+
* Ursachen für einen erhöhten Zähler: ein Interface ist down, ein Dienst startet nicht sauber, der Knoten befindet sich noch im Maintenance Mode
stehen.
+
* Maintenance Mode verlassen: '''System => High Availability => Status => Leave persistent CARP maintenance mode'''
  
Der Alias <code>LOKALE_NETZE</code> (''Firewall: Aliases'', Typ Network) enthält alle eigenen
+
== Schritt 4: Sicht des Clients ==
Netze, z. B. die LAN-, DMZ- und VPN-Bereiche.
+
* Auf dem Windows-Client prüfen, welche MAC hinter dem Gateway steckt:
 +
arp -a
 +
* Die LAN-VIP muss auf eine virtuelle MAC zeigen, nicht auf die echte NIC des Masters:
 +
192.168.1.3    00-00-5e-00-01-64
 +
* Das letzte Byte ist die VHID in hex – 0x64 = 100
 +
* Steht dort eine 08:00:27:... Adresse, arbeitet der Client an CARP vorbei direkt mit einer echten Firewall-IP
 +
* Nach einem Failover darf sich der ARP-Eintrag '''nicht''' ändern – genau das ist der Sinn der virtuellen MAC
  
=== Firewall: Settings: Advanced ===
+
== Schritt 5: Zustandssynchronisation (pfsync) ==
 +
* Läuft der pfsync-Verkehr über das SYN-Netz?
 +
tcpdump -n -i em2 proto 240
 +
* Anzahl der States auf beiden Knoten vergleichen – die Werte müssen ähnlich sein:
 +
pfctl -s state | wc -l
 +
* Ist die Zahl auf dem Backup dauerhaft 0, überträgt pfsync nicht:
 +
** '''Synchronize Peer IP''' zeigt auf die falsche Adresse
 +
** Die Allow-Regel auf dem SYN-Interface fehlt
 +
** SYN-Interface auf einem der Knoten nicht aktiviert
  
 +
== Schritt 6: Konfigurationssynchronisation (XMLRPC) ==
 +
* Auf der Master-Firewall: '''System => Log Files => General''', im Filter-Feld '''xmlrpc''' eingeben
 +
* Gesucht wird ein Eintrag wie: '''[OK] Configuration synchronized to''' https://100.64.64.2:443
 +
* Manuell anstoßen: '''System => High Availability => Status => Synchronize and reconfigure all (Push)'''
 +
* Gleichzeitig auf dem Backup mitlesen:
 +
tail -f /var/log/configd/latest.log
 
{| class="wikitable"
 
{| class="wikitable"
! Option !! Empfehlung !! Wirkung
+
! Meldung !! Ursache
 +
|-
 +
| Connection refused || Web-GUI des Backups nicht erreichbar oder falscher Port
 
|-
 
|-
| Skip rules when gateway is down || aktiv || Bei totem Gateway wird die Regel entfernt statt auf das Default-Gateway zurückzufallen – verhindert stillen Rückfall auf die falsche Leitung
+
| Authentication failed || Falsches Passwort unter "Remote System Password"
 
|-
 
|-
| Allow default gateway switching || aktiv || Fällt das Default-Gateway (WAN2GW) aus, zieht OPNsense das Default automatisch auf WAN1GW – so folgt auch der Eigenverkehr der Firewall (inkl. rekursivem DNS) der aktiven Leitung
+
| Certificate verify failed || "Verify peer" ist aktiviert, Zertifikat ist selbstsigniert
 
|-
 
|-
| Sticky connections || nur bei Lastverteilung || hält alle Verbindungen eines Clients auf derselben Leitung
+
| Endlose Sync-Schleife || Auf dem Backup ist "Synchronize Config" gefüllt – muss leer sein
 
|}
 
|}
  
== Szenarien testen ==
+
== Schritt 7: Ausgehende Verbindungen ==
 
+
* Prüfen, mit welcher Quelladresse der Client nach draußen geht:
Welche Public-IP je Leitung anliegt, prüft man direkt an den WAN-Geräten:
+
  tcpdump -n -i em1 host 192.168.HS.254
 
+
* Es muss die Virtual WAN IP (192.168.HS.X+20) erscheinen, nicht die echte IP des Masters
  curl -sS -4 --interface em1 ifconfig.co
+
* Erscheint die echte IP: Outbound-NAT steht noch auf automatisch, oder in der manuellen Regel wurde als Target nicht die VIP gewählt
62.159.72.206
 
curl -sS -4 --interface em4 ifconfig.co
 
194.59.156.244
 
 
 
'''Zieladresse für den Traceroute-Test bewusst wählen:''' weder eine Monitor-IP (9.9.9.9,
 
208.67.222.222) noch einen der konfigurierten DNS-Server (8.8.8.8, 1.1.1.1) nehmen. OPNsense legt
 
für diese Adressen Hostrouten über eine feste Leitung an – dann misst man nicht die Gatewaygruppe,
 
sondern die Hostroute.
 
  
 +
== Nützliche Befehle im Überblick ==
 
{| class="wikitable"
 
{| class="wikitable"
! Szenario !! Vorgehen !! Erwartetes Ergebnis
+
! Befehl !! Zweck
 +
|-
 +
| ifconfig em0 ; ifconfig em1 || CARP-Rolle und VIPs anzeigen
 +
|-
 +
| tcpdump -n -i em1 proto 112 || CARP-Advertisements mitlesen
 +
|-
 +
| tcpdump -n -i em2 proto 240 || pfsync-Verkehr mitlesen
 
|-
 
|-
| Normalbetrieb || <code>traceroute -n heise.de</code> von der Firewall || erster externer Hop 172.30.34.254 (WAN2GW, Tier 1)
+
| pfctl -s state {{!}} wc -l || Anzahl der Firewall-States
 
|-
 
|-
| Ausfall WAN2 || Kabel in VirtualBox trennen || Dashboard zeigt WAN2GW offline, Verkehr läuft über 192.168.HS.254 (WAN1GW)
+
| sysctl net.inet.carp.demotion || Demotion-Zähler
 
|-
 
|-
| Rückkehr WAN2 || Kabel wieder verbinden || WAN2GW wieder online, neue Verbindungen laufen über WAN2
+
| sysctl net.inet.carp.log=2 || Ausführliches CARP-Logging
 
|-
 
|-
| DNS-Test || <code>dig @8.8.8.8</code> und <code>dig @1.1.1.1</code> || beide antworten, jeder über seine Leitung
+
| tail -f /var/log/configd/latest.log || Konfigurationssync mitlesen
 
|-
 
|-
| Zugriff intern || Ping in DMZ bei totem WAN2 || funktioniert weiter (Regel 2 ohne Gateway)
+
| configctl filter reload || Regelwerk neu laden
 
|}
 
|}
  
'''Wer routet gerade wohin?''' Drei Instanzen entscheiden unabhängig und lassen sich getrennt ablesen:
+
==Netzwerkschnittstellen==
 +
=== Master ===
 +
em0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
 +
description: LAN (lan)
 +
options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
 +
ether 08:00:27:c4:a2:6f
 +
inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
 +
'''inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255 vhid 100'''
 +
'''carp: MASTER vhid 100 advbase 1 advskew 0'''
 +
      '''peer 224.0.0.18 peer6 ff02::12'''
 +
media: Ethernet autoselect (1000baseT <full-duplex>)
 +
status: active
 +
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
  
* das '''Default-Gateway''' (Eigenverkehr der Firewall) unter ''Interfaces: Diagnostics: Routes''
+
em1: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
* die '''States''' (welche Verbindung über welches Interface läuft) unter ''Firewall: Diagnostics: States''
+
description: WAN (wan)
* das '''Policy Routing''' der Gruppe – Statuswechsel mit Zeitstempel im ''System: Gateways: Log File''
+
options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
 +
ether 08:00:27:61:6f:6d
 +
inet 192.168.HS.X+40 netmask 0xffffff00 broadcast 192.168.HS.255
 +
'''inet 192.168.HS.X+20 netmask 0xffffff00 broadcast 192.168.HS.255 vhid X'''
 +
'''carp: MASTER vhid X advbase 1 advskew 0'''
 +
      '''peer 224.0.0.18 peer6 ff02::12'''
 +
media: Ethernet autoselect (1000baseT <full-duplex>)
 +
status: active
 +
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
  
Nach einem Failover ist für ~10–20 s ein Mischbild normal: bestehende States bleiben auf der alten
+
=== Backup ===
Leitung, bis sie ablaufen; nur neue Verbindungen nehmen sofort den neuen Weg.
+
em0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
 +
description: LAN (lan)
 +
options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
 +
ether 08:00:27:1c:44:8b
 +
inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
 +
'''inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255 vhid 100'''
 +
'''carp: BACKUP vhid 100 advbase 1 advskew 100'''
 +
      '''peer 224.0.0.18 peer6 ff02::12'''
 +
media: Ethernet autoselect (1000baseT <full-duplex>)
 +
status: active
 +
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
  
Weitere Statusanzeige: ''Lobby: Dashboard'' (Widget Gateways).
+
em1: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
 +
description: WAN (wan)
 +
options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
 +
ether 08:00:27:95:9b:4b
 +
inet 192.168.HS.X+60 netmask 0xffffff00 broadcast 192.168.HS.255
 +
'''inet 192.168.HS.X+20 netmask 0xffffff00 broadcast 192.168.HS.255 vhid X'''
 +
'''carp: BACKUP vhid X advbase 1 advskew 100'''
 +
      '''peer 224.0.0.18 peer6 ff02::12'''
 +
media: Ethernet autoselect (1000baseT <full-duplex>)
 +
status: active
 +
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
  
== Umsetzung ==
+
* Der Master hat '''advskew 0''', das Backup '''advskew 100'''. Diesen Wert setzt OPNsense beim Sync automatisch – er wird nicht von Hand vergeben.
  
* https://docs.opnsense.org/manual/how-tos/multiwan.html
+
==Wird Synchronisiert?==
 +
;Master
 +
* System
 +
** High Availability
 +
*** Status
 +
**** Synchronize and reconfigure all (Push)
 +
;Backup
 +
tail -f /var/log/configd/latest.log
 +
* Hier sollte man die Übertragung sehen.

Aktuelle Version vom 4. September 2026, 07:07 Uhr

Plan

Platzhalter in diesem Artikel

Platzhalter Bedeutung Beispiel
HS Drittes Oktett des Schulungsnetzes (WAN), wird vom Trainer vorgegeben 4
X Deine Teilnehmernummer, wird vom Trainer vorgegeben 13
  • Beispiel für X=13 und HS=4: WAN Master 192.168.4.53, WAN Backup 192.168.4.73, WAN-VIP 192.168.4.33, VHID 13
  • Alle Passwörter in diesem Artikel sind Laborwerte und dürfen so niemals in eine produktive Umgebung übernommen werden.

Wichtig

  • Die Netzwerkkarten für LAN und WAN müssen im Hypervisor in den Promiscuous-Modus geschaltet werden – nicht in OPNsense.
    • VirtualBox: Maschine => Ändern => Netzwerk => Adapter => Erweitert => Promiscuous-Modus: Alle erlauben
    • Proxmox: Bridge ohne MAC-Filter bzw. entsprechende Bridge-Einstellung
  • Das gilt sowohl für den Master als auch für das Backup.
Begründung
  • CARP verwendet virtuelle MAC-Adressen für die gemeinsame VIP. In virtualisierten Umgebungen werden Frames mit diesen MAC-Adressen vom Hypervisor standardmäßig verworfen, da sie nicht der echten VM-NIC zugeordnet sind. Ohne aktivierten Promiscuous-Modus erreichen CARP-Advertisements den Partner nicht, was zu Fehldetektion, unerwünschtem Failover und HA-Inkonsistenzen führt.

Vorbereitung

  • Zwei OPNsense-Installationen mit jeweils mind. 3 Netzwerkkarten
  • Auf beiden Maschinen muss die gleiche OPNsense-Version laufen
  • Die Anzahl der Netzwerkkarten muss auf beiden Maschinen gleich sein
  • Die Reihenfolge und Anzahl der Netzwerkschnittstellen muss auf beiden Maschinen identisch sein!
  • Empfehlung für beide Maschinen:
    • em0: LAN
    • em1: WAN
    • em2: SYN
  • Am Anfang sollten so wenige Dienste wie möglich laufen

opnsense-template klonen

  • Beim Klonen "Neue MAC-Adressen für alle Netzwerkkarten erzeugen" auswählen

IP-Adressen der Backup Firewall

Template klonen als opns-ha2

System-Settings: General

  • Hostname: opns-ha2
  • Theme: opnsense-dark
  • Gateway anlegen: 192.168.HS.254 und später WAN zuordnen
  • em0 (LAN): 192.168.1.2/24
  • em1 (WAN): 192.168.HS.X+60/24
  • em2 (SYN): 100.64.64.2/30

IP-Adressen der Master Firewall

Template klonen als opns-ha1

System-Settings: General

  • Hostname: opns-ha1
  • Theme: opnsense
  • Gateway anlegen: 192.168.HS.254 und später WAN zuordnen
  • em0 (LAN): 192.168.1.1/24 (bereits aus dem Template)
  • em1 (WAN): 192.168.HS.X+40/24
  • em2 (SYN): 100.64.64.1/30

Übersicht

Master (opns-ha1) Backup (opns-ha2) VIP VHID
LAN (em0) 192.168.1.1 192.168.1.2 192.168.1.3 100
WAN (em1) 192.168.HS.X+40 192.168.HS.X+60 192.168.HS.X+20 X
SYN (em2) 100.64.64.1 100.64.64.2
  • Die VHID muss nur innerhalb einer Broadcast-Domäne eindeutig sein, der Wertebereich ist 1 bis 255.
  • Da sich alle Teilnehmer das WAN-Segment teilen, wird dort die Teilnehmernummer X verwendet (1 bis 13).
  • Das LAN ist pro Teilnehmer ein eigenes, isoliertes Segment. Dort steht deshalb bei allen Teilnehmern fest die 100. Der Abstand zum WAN-Bereich ist Absicht: dreistellig = LAN, zweistellig = WAN.

Firewall Regeln (beide Firewalls)

  • Auf dem WAN-Interface muss das Protokoll CARP akzeptiert werden
  • Dazu im Menü Firewall => Rules => WAN eine Allow-Regel erstellen, die auf das CARP-Protokoll matcht
  • Auf dem LAN-Interface genügt die Default-Regel "Default allow LAN to any" – sie erlaubt jedes Protokoll
    • Wird diese Regel später durch restriktive Regeln ersetzt, muss dort eine eigene CARP-Regel ergänzt werden, sonst bricht der Cluster im LAN auseinander
  • Für das SYN-Interface eine Standard-Allow-Regel erstellen, die alles erlaubt

Virtuelle IPs (Master Firewall)

  • Die virtuellen IPs werden von den Knoten des HA-Clusters geteilt, sobald ein Ausfall erkannt wird
  • Somit wird dafür gesorgt, dass die virtuelle IP immer erreichbar ist
  • Die virtuelle IP wird nur auf der Master Firewall eingestellt und an die Backups mitgeteilt
  • Dazu muss man im Menü Interfaces => Virtual IPs => Settings an allen Schnittstellen bis auf das SYN-Interface die gewünschten IPs vergeben
  • Über das [+] auf der rechten Seite muss man folgende Einträge machen:

virtuelle WAN IP

Parameter Wert
Mode CARP
Interface WAN
Address 192.168.HS.X+20/24
Virtual Password radler
VHID Group X
Advertising Frequency 1
Description Virtual WAN IP

virtuelle LAN IP

Parameter Wert
Mode CARP
Interface LAN
Address 192.168.1.3/24
Virtual Password radler
VHID Group 100
Advertising Frequency 1
Description Virtual LAN IP

Source NAT (Master Firewall)

  • Da die virtuelle IP für ausgehende Verbindungen benutzt werden soll, muss die automatische Regelgenerierung ausgeschaltet werden
  • Im Menü Firewall => NAT => SNAT den Modus auf Manual stellen
  • Dann die folgende Regel erstellen:
Parameter Wert
Interface WAN
Source LAN network
Translate Source IP Virtual WAN IP (192.168.HS.X+20)

High Availability Konfiguration (Master Firewall)

  • Die eigentliche HA-Einstellung erfolgt über das Menü System => High Availability => Settings:
Parameter Wert
Synchronize all states via SYN
Sync compatibility OPNsense 24.7 or above
Synchronize Peer IP 100.64.64.2
Synchronize Config 100.64.64.2
Verify peer deaktiviert
Remote System Username root
Remote System Password radler
Services Aliases, Firewall Rules, NAT, Virtual IPs
  • "Verify peer" bleibt deaktiviert, weil die Web-GUI der Gegenstelle ein selbstsigniertes Zertifikat verwendet.

High Availability Konfiguration (Backup Firewall)

  • Hier darf im Menü System => High Availability => Settings nur folgendes eingestellt werden:
Parameter Wert
Synchronize all states via SYN
Sync compatibility OPNsense 24.7 or above
Synchronize Peer IP 100.64.64.1
Synchronize Config leer
Verify peer deaktiviert
Remote System Username leer
Remote System Password leer
Services Nothing selected
  • Synchronize Config muss auf dem Backup leer bleiben. Trägt man hier den Master ein, schieben sich beide Knoten gegenseitig ihre Konfiguration zu.

Client im LAN

  • Der Windows-Client (192.168.1.50) muss als Gateway und als DNS-Server die LAN-VIP 192.168.1.3 erhalten – nicht die 192.168.1.1
  • Wird die echte IP des Masters eingetragen, ist der Client beim Ausfall des Masters trotz funktionierendem Cluster offline
  • Bei Verwendung eines DHCP-Servers muss dieser die VIP als Gateway und DNS verteilen

Endergebnis

Master

  • System
    • High Availability
      • Status
  • Hier müssen beide Spalten gefüllt sein und auf beiden Knoten die gleichen Dienste erscheinen:
Service Description
configd Configd
cron Cron
hostwatch Hostwatch
login Users and Groups
ntpd Ntpd
openssh Secure Shell
pf Packet Filter
routing System routing
sysctl System tunables
syslog-ng Syslog-ng
unbound Unbound DNS
webgui Web GUI
Wichtig
 Syncronize and reconfigure all

Slave

  • System
    • High Availability
      • Status
  • Auf der Backup-Firewall erscheint hier die Warnung, dass die XMLRPC-Konfiguration unvollständig sei.
  • Diese Meldung kann ignoriert werden: Das Backup empfängt nur passiv, deshalb sind die XMLRPC-Felder dort absichtlich leer und werden fälschlicherweise als "unvollständig" markiert. Solange die Master-Firewall auf Version 24.7 eingestellt ist und die Daten erfolgreich überträgt, arbeitet der Cluster technisch einwandfrei.

Failover testen

  • Auf dem Client einen Dauerping nach draußen starten:
ping -t 192.168.HS.254
  • Auf dem Master: Interfaces => Virtual IPs => Status => Enter Persistent CARP Maintenance Mode
  • Erwartetes Verhalten:
    • Das Backup wechselt für beide VHIDs von BACKUP auf MASTER
    • Der Ping läuft weiter oder verliert maximal ein bis zwei Pakete
  • Kontrolle auf beiden Knoten:
ifconfig em0 ; ifconfig em1
  • Zurückschalten über Leave Persistent CARP Maintenance Mode auf dem Master
  • Zweiter Test: Master hart ausschalten (VM stoppen) und das gleiche Verhalten prüfen

Debugging

Vorgehen

  • Von unten nach oben prüfen: erst CARP (Layer 2/3), dann pfsync (States), dann XMLRPC (Konfiguration)
  • Ein Cluster kann sauber synchronisieren und trotzdem kein Failover können – und umgekehrt

Schritt 1: CARP-Status

  • Auf beiden Knoten:
ifconfig em0 ; ifconfig em1
  • Erwartetes Bild:
Knoten LAN (vhid 100) WAN (vhid X)
Master MASTER, advskew 0 MASTER, advskew 0
Backup BACKUP, advskew 100 BACKUP, advskew 100
  • In der GUI: Interfaces => Virtual IPs => Status
  • CARP global ein-/ausgeschaltet:
sysctl net.inet.carp.allow
  • Ausführlichere CARP-Meldungen im Log einschalten:
sysctl net.inet.carp.log=2

Schritt 2: Beide Knoten sind MASTER (Split Brain)

  • Das häufigste Fehlerbild im Labor. Beide Knoten sehen den Partner nicht und übernehmen die VIP.
  • Prüfen, ob die Advertisements des Partners überhaupt ankommen:
tcpdump -n -i em1 proto 112
tcpdump -n -i em0 proto 112
  • Man muss die Pakete beider Knoten sehen (Quelle = jeweils die echte Interface-IP)
Beobachtung Ursache
Nur eigene Pakete sichtbar Promiscuous-Modus im Hypervisor fehlt
Gar keine Pakete sichtbar VIP nicht angelegt oder Interface down
Pakete kommen an, trotzdem beide MASTER CARP-Allow-Regel auf dem Interface fehlt
Pakete mit fremder VHID Anderer Teilnehmer nutzt die gleiche VHID
  • Weitere Ursachen bei Split Brain:
    • Unterschiedliches Virtual Password auf den beiden Knoten
    • Unterschiedliche VHID auf den beiden Knoten
    • Unterschiedliche Advertising Frequency

Schritt 3: Kein Failover trotz korrektem Status

  • Demotion-Zähler prüfen – ist er größer als 0, bleibt der Knoten absichtlich BACKUP:
sysctl net.inet.carp.demotion
  • Ursachen für einen erhöhten Zähler: ein Interface ist down, ein Dienst startet nicht sauber, der Knoten befindet sich noch im Maintenance Mode
  • Maintenance Mode verlassen: System => High Availability => Status => Leave persistent CARP maintenance mode

Schritt 4: Sicht des Clients

  • Auf dem Windows-Client prüfen, welche MAC hinter dem Gateway steckt:
arp -a
  • Die LAN-VIP muss auf eine virtuelle MAC zeigen, nicht auf die echte NIC des Masters:
192.168.1.3    00-00-5e-00-01-64
  • Das letzte Byte ist die VHID in hex – 0x64 = 100
  • Steht dort eine 08:00:27:... Adresse, arbeitet der Client an CARP vorbei direkt mit einer echten Firewall-IP
  • Nach einem Failover darf sich der ARP-Eintrag nicht ändern – genau das ist der Sinn der virtuellen MAC

Schritt 5: Zustandssynchronisation (pfsync)

  • Läuft der pfsync-Verkehr über das SYN-Netz?
tcpdump -n -i em2 proto 240
  • Anzahl der States auf beiden Knoten vergleichen – die Werte müssen ähnlich sein:
pfctl -s state | wc -l
  • Ist die Zahl auf dem Backup dauerhaft 0, überträgt pfsync nicht:
    • Synchronize Peer IP zeigt auf die falsche Adresse
    • Die Allow-Regel auf dem SYN-Interface fehlt
    • SYN-Interface auf einem der Knoten nicht aktiviert

Schritt 6: Konfigurationssynchronisation (XMLRPC)

  • Auf der Master-Firewall: System => Log Files => General, im Filter-Feld xmlrpc eingeben
  • Gesucht wird ein Eintrag wie: [OK] Configuration synchronized to https://100.64.64.2:443
  • Manuell anstoßen: System => High Availability => Status => Synchronize and reconfigure all (Push)
  • Gleichzeitig auf dem Backup mitlesen:
tail -f /var/log/configd/latest.log
Meldung Ursache
Connection refused Web-GUI des Backups nicht erreichbar oder falscher Port
Authentication failed Falsches Passwort unter "Remote System Password"
Certificate verify failed "Verify peer" ist aktiviert, Zertifikat ist selbstsigniert
Endlose Sync-Schleife Auf dem Backup ist "Synchronize Config" gefüllt – muss leer sein

Schritt 7: Ausgehende Verbindungen

  • Prüfen, mit welcher Quelladresse der Client nach draußen geht:
tcpdump -n -i em1 host 192.168.HS.254
  • Es muss die Virtual WAN IP (192.168.HS.X+20) erscheinen, nicht die echte IP des Masters
  • Erscheint die echte IP: Outbound-NAT steht noch auf automatisch, oder in der manuellen Regel wurde als Target nicht die VIP gewählt

Nützliche Befehle im Überblick

Befehl Zweck
ifconfig em0 ; ifconfig em1 CARP-Rolle und VIPs anzeigen
tcpdump -n -i em1 proto 112 CARP-Advertisements mitlesen
tcpdump -n -i em2 proto 240 pfsync-Verkehr mitlesen
wc -l Anzahl der Firewall-States
sysctl net.inet.carp.demotion Demotion-Zähler
sysctl net.inet.carp.log=2 Ausführliches CARP-Logging
tail -f /var/log/configd/latest.log Konfigurationssync mitlesen
configctl filter reload Regelwerk neu laden

Netzwerkschnittstellen

Master

em0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
	description: LAN (lan)
	options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
	ether 08:00:27:c4:a2:6f
	inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
	inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255 vhid 100
	carp: MASTER vhid 100 advbase 1 advskew 0
	      peer 224.0.0.18 peer6 ff02::12
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
em1: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
	description: WAN (wan)
	options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
	ether 08:00:27:61:6f:6d
	inet 192.168.HS.X+40 netmask 0xffffff00 broadcast 192.168.HS.255
	inet 192.168.HS.X+20 netmask 0xffffff00 broadcast 192.168.HS.255 vhid X
	carp: MASTER vhid X advbase 1 advskew 0
	      peer 224.0.0.18 peer6 ff02::12
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Backup

em0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
	description: LAN (lan)
	options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
	ether 08:00:27:1c:44:8b
	inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
	inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255 vhid 100
	carp: BACKUP vhid 100 advbase 1 advskew 100
	      peer 224.0.0.18 peer6 ff02::12
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
em1: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
	description: WAN (wan)
	options=48500b8<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
	ether 08:00:27:95:9b:4b
	inet 192.168.HS.X+60 netmask 0xffffff00 broadcast 192.168.HS.255
	inet 192.168.HS.X+20 netmask 0xffffff00 broadcast 192.168.HS.255 vhid X
	carp: BACKUP vhid X advbase 1 advskew 100
	      peer 224.0.0.18 peer6 ff02::12
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
  • Der Master hat advskew 0, das Backup advskew 100. Diesen Wert setzt OPNsense beim Sync automatisch – er wird nicht von Hand vergeben.

Wird Synchronisiert?

Master
  • System
    • High Availability
      • Status
        • Synchronize and reconfigure all (Push)
Backup
tail -f /var/log/configd/latest.log
  • Hier sollte man die Übertragung sehen.