TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/strongswan/strongswan/llms.txt
Use this file to discover all available pages before exploring further.
ha plugin provides active-passive failover for strongSwan gateways. It synchronizes IKE_SA and CHILD_SA state from the active node to a passive standby, so that the standby can take over existing tunnels without requiring clients to renegotiate.
Architecture
keepalived) or ucarp. The active node handles all IKE exchanges and sends synchronization messages to the passive node over a dedicated UDP channel. When the active node stops sending heartbeats, the passive node activates its synchronized SAs and begins serving traffic.
The
ha plugin handles SA synchronization only. Virtual IP management and failover triggering must be provided by an external tool such as keepalived or ucarp.Requirements
- Both nodes must be reachable from each other on the sync address (layer-2 adjacency recommended, but a routed dedicated sync link also works).
- Both nodes must have identical
swanctl.confconnection configurations. - The
haplugin requires theCAP_CHOWNcapability at startup to manage its control socket. - Kernel IPsec support (
kernel-netlinkplugin on Linux).
Configuration
Add theha plugin configuration under charon { plugins { } } in strongswan.conf.
Configuration options
| Option | Default | Description |
|---|---|---|
local | — | This node’s IP address for the sync channel. Required. |
remote | — | Peer node’s IP address for the sync channel. Required. |
secret | — | Shared secret used to authenticate sync messages (HMAC-SHA1). If omitted, messages are unauthenticated. |
fifo_interface | yes | Create a FIFO control interface to manually activate/deactivate segments. |
monitor | yes | Enable heartbeat monitoring to detect peer failure. |
resync | yes | Request full resynchronization from the peer node on plugin startup. |
segment_count | 1 | Number of HA segments (maximum 16). Segments allow splitting SA ownership between nodes. |
heartbeat_delay | 1000 | Interval in milliseconds between heartbeat messages. |
heartbeat_timeout | 2100 | Milliseconds without a heartbeat before the peer is considered failed. |
autobalance | 0 | Interval in seconds to automatically rebalance segments. 0 disables. |
buflen | 2048 | Buffer size for received HA messages in bytes. Increase for large DH groups (e.g. modp4096). |
Setting up a two-node cluster
Configure both nodes identically
Deploy the same
swanctl.conf connection definitions on both nodes. The HA plugin syncs SA state, not configuration — both nodes must know about all connections.Configure the ha plugin on each node
On node 1 (On node 2 (
192.168.1.1):192.168.1.2), swap local and remote:Configure the virtual IP with keepalived
Install
keepalived on both nodes and configure VRRP to manage the shared virtual IP. The virtual IP should be the address clients and peers connect to.Start the daemons
Start strongSwan on the passive node first, then on the active node. The active node will push its SA state to the passive node automatically if
resync = yes.How SA synchronization works
The ha plugin hooks into charon’s event bus via three listeners:ha_ike— listens for IKE_SA events (establish, rekey, delete) and serializes state into sync messages.ha_child— listens for CHILD_SA events and sends kernel SA parameters (SPIs, keys, traffic selectors) to the peer.ha_segments— tracks which node is active for each segment and handles heartbeat exchange.
local address and directed to the remote address. When a secret is configured, messages are protected by HMAC-SHA1 to prevent injection of forged SA state.
Segment-based load distribution
Withsegment_count > 1, you can distribute SA ownership across segments. Each IKE_SA is hashed into a segment. You can manually activate or deactivate segments via the FIFO interface (fifo_interface = yes) at /var/run/charon.ha:
autobalance set to a non-zero interval, the plugin periodically redistributes segments to equalize load between nodes.
Limitations
- Active-passive only. Both nodes cannot process IKE traffic simultaneously. There is no active-active clustering mode.
- No built-in VIP management. You must use an external tool (keepalived, ucarp, or custom scripting) to move the virtual IP on failover.
- IKEv1 sync messages are larger. IKEv1 sync includes DH public factors; increase
buflenif usingmodp4096or larger groups. - In-flight exchanges are lost. If the active node fails mid-handshake, clients must retry. Only completed SAs are synced.
- Same plugin version required. Both nodes must run the same strongSwan version to ensure sync message compatibility.