Skip to main content
RunBook Academy

OPNsenseXXVI · High Availability FundamentalsConfiguration synchronisation

Configuration synchronisation concepts — keeping the two nodes in lockstep

Intermediate⏱ ~13 minconfigctlpfctlsystat

What you'll learn

  • Distinguish configuration synchronisation from state synchronisation
  • Explain the XMLRPC-based configuration sync in OPNsense
  • Identify what is synchronised and what is not
  • Recognise the discipline of staged configuration changes
  • Identify the failure modes of misconfigured sync (silent drift, broken HA)

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-15

Not yet marked complete on this device.

A two-firewall HA deployment has a subtle requirement that is easy to overlook: the two nodes must have the same configuration. If node A has a firewall rule that node B does not, the failover produces a behavioural change — node A forwards the traffic, node B drops it. The application does not know the configuration changed; it just sees connections that worked yesterday failing today. Configuration synchronisation is the mechanism that keeps the two nodes in lockstep. This lesson covers what configuration sync does, the OPNsense XMLRPC model, what is and is not synchronised, and the discipline of staged changes.

State sync versus configuration sync

The two are independent mechanisms serving different purposes:

MechanismWhat movesWhen it movesLifetime
pfsync (state sync)PF state table entries — runtime connection stateIn real time, as states are created/changed/deletedRuntime only — does not persist
XMLRPC sync (config sync)Configuration — firewall rules, NAT rules, aliases, VIPs, DHCP leasesOn demand, after the operator commits a changePersisted — survives reboot

State sync handles the runtime — what is happening on the firewall right now. Config sync handles the configuration — what the firewall should do. The two mechanisms do not interact: state sync moves running state from primary to backup; config sync moves the saved configuration from primary to backup.

The trap is to confuse them. A deployment with config sync but no state sync will fail over correctly (the backup has the same configuration) but drop every active connection (the backup has no state). A deployment with state sync but no config sync will keep connections alive during failover but may apply different rules on the new master than the old one.

The XMLRPC sync model

OPNsense’s configuration synchronisation uses XMLRPC over HTTPS. The flow:

  1. Operator commits a change. The operator changes a rule, adds an alias, modifies a VIP. The change is saved on the local node (the primary, the one the operator is logged into).
  2. Local node applies the change. The local node writes the configuration, regenerates /tmp/rules.debug, and reloads PF. The change is live on the primary.
  3. Local node synchronises to the backup. If XMLRPC sync is configured, the local node opens an HTTPS connection to the backup and pushes the configuration. The backup writes the configuration and reloads PF.
  4. Both nodes have the same configuration. Within a few seconds, the backup has the same configuration as the primary.

The XMLRPC sync is one-directional: the primary pushes to the backup. The backup does not push back. This means the operator should make all changes on the primary (the master node); making changes on the backup risks the primary overwriting them on the next sync.

Read-only / SafeHA sync status
$ configctl ha carp status
HA: CARP status
Synchronise state: pfsync
Synchronise configuration: enabled
Master node: primary.example.com
Backup node: secondary.example.com
Last sync: 2026-08-15 12:34:56 (primary -> secondary)
Status: in-sync

Illustrative output

What is and is not synchronised

The XMLRPC sync covers most of the configuration — firewall rules, NAT, aliases, VIPs, DHCP, DNS, IPsec, certificates, users. Some items are explicitly excluded:

  • Hostnames and IP addresses of the firewall itself. Each node has its own identity — the IP on the sync interface, the hostname, the management IP. These are not synced because they would conflict.
  • CARP configuration itself. The VHID, the password, the skew. These are node-specific (the primary and backup have different skews); syncing them would invert the roles.
  • System logs. Each node logs independently; logs are not synced.
  • RRD graphs and monitoring data. Each node collects its own performance data; the data is not synced.
  • State table. Synced via pfsync, not via XMLRPC.
  • Installed packages and plugins. Each node manages its own package state; the package list is synced but the install state is not.

The general rule: configuration items that should be identical across nodes (rules, aliases, VIPs) are synced. Items that are inherently per-node (IP addresses, skew values, logs) are not. The operator can see the full list in the XMLRPC sync settings page (System → High Availability → Settings).

The discipline of staged changes

The XMLRPC sync model implies a discipline: make changes on the primary, let them sync to the backup, verify the backup has them, then move on. The discipline prevents a class of failures:

  • Changes lost to overwriting. The operator who makes a change on the backup, then makes a different change on the primary, finds the primary’s change pushed to the backup and the backup’s change gone. The change is silent — the GUI does not warn.
  • Partial sync. A change is committed but the XMLRPC sync fails (network issue, backup down). The primary has the change; the backup does not. The configurations are now different. Failover produces behavioural change.
  • Stale state on the backup. The backup has an older configuration than the primary. A connection that was allowed on the primary may be dropped on the backup. The user sees intermittent failures — sometimes the connection works, sometimes not.

The staged-change discipline:

  1. Make the change on the primary.
  2. Verify the sync status (configctl ha carp status shows “in-sync” or the equivalent).
  3. Verify the backup has the change (log in to the backup, confirm the rule exists).
  4. Test the change (the production traffic path, or a synthetic test).
  5. Move on.

If the sync fails, the operator fixes the sync before making more changes. A backlog of unsynced changes is hard to reason about.

Production failure modes

Sync silently disabled. The operator changes a rule on the primary; the backup does not update. The XMLRPC sync was disabled at some point (a misconfiguration, a forgotten setting during initial setup). The operator does not notice because the GUI does not warn.

Sync fails intermittently. The sync connection between primary and backup is unstable (a flaky switch port, a transient firewall block). Some changes sync, others do not. The configurations drift slowly. A failover produces an inconsistent state.

Sync overwrites a manual change. The operator makes a temporary change on the backup (e.g., adds a rule to debug a problem), forgets about it, and the next primary change wipes it out. The temporary fix disappears silently.

Backup is unreachable when the change is made. The operator changes the primary; the sync fails because the backup is offline. The primary has the change; the backup does not. The operator assumes the sync will happen later — but the sync only happens at the moment of the change.

Summary

  • Configuration sync keeps the two nodes’ saved configurations identical; state sync keeps the runtime state in sync.
  • OPNsense uses XMLRPC over HTTPS, one-directional (primary pushes to backup).
  • Most configuration is synced: rules, NAT, aliases, VIPs, services. Node-specific items are not: IPs, hostnames, skews, logs.
  • The staged-change discipline: change on primary, verify sync, verify backup, test.
  • Failure modes include silently disabled sync, intermittent sync failures, and manual changes lost to sync.

Knowledge check · 4 questions

  1. Q1. A deployment has XMLRPC config sync enabled but pfsync disabled. The primary fails over to the backup. What is the most likely outcome?

  2. Q2. CARP skew values are synchronised between the two nodes via XMLRPC sync.

  3. Q3. Which of the following are good operational practices for HA configuration sync? Select all that apply.

  4. Q4. The operator makes a firewall rule change on the primary and sees configctl ha carp status show "pending". What does this mean?

Passing score: 75%. Answers are checked in this browser.