Skip to content

4. High availability — CARP + pfSync + config sync

This is the hinge of the whole build: after config sync is on, you configure the primary only and OPNsense replicates. Get it working before the routing/NAT/firewall pages so you're not doubling that work by hand.

Three independent mechanisms, don't conflate them:

Mechanism Carries Path
CARP which node is master (per VIP) heartbeats on WAN + server VLANs + pfSync
pfSync firewall state table the PFSYNC bond only
XMLRPC config sync configuration master→backup over PFSYNC

4.1 pfSync — state synchronisation

System ▸ High Availability ▸ Settings, top half:

Field Value
Synchronize States on
Synchronize Interface PFSYNC
Synchronize Peer IP the peer's PFSYNC /30 address
pfSync version 1400 (must match on both nodes)

Do this on both nodes, each pointing at the other's PFSYNC IP. State sync is low-bandwidth (~40 Mbps even at 50k conn/s; a 5M-state bulk resync on rejoin is ~4 s over 1G — §2), so 1G active-backup is ample.

4.2 XMLRPC config sync — master pushes to backup

Same page, bottom half — configure on the PRIMARY (FW-01) ONLY:

Field Value
Synchronize Config to IP the backup's PFSYNC IP (<FW02 PFSYNC>)
Remote System Username a dedicated sync admin account
Remote System Password its password
Sync services / categories tick the categories you want replicated (see below)

Leave 'Synchronize Config to IP' BLANK on the backup

Only the primary pushes. If the backup also has a sync target, they fight. This is the single most important HA setting to get directional.

What to sync (and what not to)

Tick the categories that are identical across nodes: Firewall Rules, Aliases, NAT, Virtual IPs (CARP), Static Routes, DHCP, Certificates, FRR/OSPF-BGP (if the plugin offers it), Users/Groups.

Do NOT rely on sync for anything per-node — it doesn't carry interface assignment, per-node /31 addresses, or system tunables. Those you set on both nodes by hand (page 2, page 10).

Verify advskew is NOT flattened by VIP sync

CARP VIP sync copies the VIP definition. Confirm on the backup that its advskew is still <CARP_ADVSKEW_BACKUP> (100), not 0 — if sync copied the primary's 0, both nodes tie and election falls to an IP tiebreak. If it does flatten, set the backup's advskew locally after each sync, or keep Virtual IPs out of the synced categories and manage VIPs on both nodes. Test this deliberately (page 11).

4.3 CARP heartbeat interfaces

CARP advertises on every interface that has a CARP VIP — here that's the server VLANs and the public VIP carrier — plus you should ensure the pfSync bond path carries heartbeats too. Multiple independent heartbeat paths mean a single link failure can't cause split-brain (both nodes master). No dedicated heartbeat port is needed (§6).

  • System ▸ High Availability ▸ Status shows MASTER/BACKUP per VIP. After sync, FW-01 should be MASTER on all VIPs, FW-02 BACKUP on all.

4.4 Preempt

Leave preempt on (default) so the designated primary reclaims master when it recovers. Because FRR is CARP-gated (page 5), a flap causes a few seconds of BGP reconvergence on each transition — acceptable, and BFD keeps it short. If flapping becomes a problem, that's a link issue to fix, not a reason to disable preempt.

4.5 Prove HA before moving on

  1. On Status, confirm FW-01 = MASTER everywhere, FW-02 = BACKUP everywhere.
  2. Create a throwaway alias on FW-01, Apply, and confirm it appears on FW-02 within a few seconds — config sync works.
  3. Delete the throwaway alias.
  4. Don't test failover for real until routing is up (page 5) — a failover now just moves VIPs with nothing behind them.

Gate

Once config sync demonstrably replicates FW-01 → FW-02, the rest of the build is primary-only unless a page says otherwise. That halves the remaining work and removes a whole class of drift.