FreeIPA Replication

Topology design, ipa-replica-install, agreement management, promoting replicas to CA/KRA, segment design, agreement states, and recovering from split-brain.

If you only remember six things
  • Multi-master, not primary/secondary. Every replica can write.
  • At least two CA replicas. If your only CA dies mid-renewal, you are having a very long day.
  • Prefer a mesh of 3–4 over a long chain. Latency and blast radius are both better.
  • Each server has a 389-DS server ID baked into agreements — never rename an IPA host.
  • Segments define "who replicates to whom". Drawing the graph first saves a weekend.
  • Back up from one host at a time, and test the restore on a throwaway — replicas are not a backup.

Topology: star, chain, mesh

An IPA topology is a graph whose nodes are servers and whose edges are replication agreements. Three common shapes:

Star                Chain                Mesh (3-host full)
                                          ipa1
   ipa1             ipa1---ipa2          /    \
   /|\               |                  /      \
  / | \              ipa3             ipa2----ipa3
ipa2 ipa3 ipa4       |
                    ipa4
ShapeProsCons
StarSimple to draw; hub is obvious.Hub failure partitions the network. No redundancy for replication traffic.
ChainMinimal agreements; fine across slow links.A break anywhere cuts the far end off. Convergence latency sums across hops.
Mesh (3–4 nodes)No single-node partition; short paths. Most common "real" deployment.O(n²) agreements — at 10+ nodes it gets busy.
Hybrid / regionalMesh inside a site; one or two cross-site links between site "gateways".Plan carefully; cross-site breakage is felt more.
Guideline: for ≤4 servers, use a full mesh. For 5–12, a mesh within each site plus two cross-site links. Beyond that, you are managing enough servers to warrant professional advice — but you will rarely need that many.

A worked three-host example

Three servers in one site, full mesh:

ipa1.example.internal   10.0.0.11   CA + KRA + DNS
ipa2.example.internal   10.0.0.12   CA + DNS
ipa3.example.internal   10.0.0.13   DNS only

Segments (ca suffix and domain suffix each):
  ipa1 <---> ipa2
  ipa1 <---> ipa3
  ipa2 <---> ipa3

Step 1 — First server (ipa1)

# On ipa1 — the first CA
ipa-server-install \
  --realm EXAMPLE.INTERNAL --domain example.internal \
  --hostname ipa1.example.internal \
  --ds-password 'REDACTED' --admin-password 'REDACTED' \
  --setup-dns --auto-forwarders \
  --setup-kra \
  --unattended

Step 2 — Second replica (ipa2, also CA)

# On ipa2 — join the realm first with a client install, or let replica-install do it.
ipa-client-install --domain example.internal --server ipa1.example.internal \
  --realm EXAMPLE.INTERNAL --unattended \
  --principal admin --password 'REDACTED'

ipa-replica-install \
  --setup-ca --setup-dns --auto-forwarders \
  --principal admin --admin-password 'REDACTED' \
  --unattended

Step 3 — Third replica (ipa3, DNS only)

# On ipa3
ipa-client-install --domain example.internal --server ipa1.example.internal \
  --realm EXAMPLE.INTERNAL --unattended \
  --principal admin --password 'REDACTED'

ipa-replica-install --setup-dns --auto-forwarders \
  --principal admin --admin-password 'REDACTED' \
  --unattended

By default, ipa-replica-install creates a single agreement to the server it was installed from. That gives you a chain. Add the missing edges to make it a mesh:

# From any server — these commands use the topology plugin on the server itself.
ipa topologysegment-add realm       ipa2-ipa3 \
    --leftnode=ipa2.example.internal --rightnode=ipa3.example.internal
ipa topologysegment-add ca          ipa2-ipa3 \
    --leftnode=ipa2.example.internal --rightnode=ipa3.example.internal

There are two suffixes you typically care about: realm (the domain suffix, dc=example,dc=internal) and ca (o=ipaca). Add segments for each suffix that the pair of servers both host.

ipa-replica-install basics

Common flags

FlagPurpose
--setup-caInstall Dogtag on this replica (needed if you want this host to issue certs)
--setup-kraInstall the Key Recovery Authority (Vault for secrets, not HashiCorp's)
--setup-dnsInstall the IPA DNS (bind-dyndb-ldap)
--server=<hostname>Which existing server to join from (optional; DNS SRV is used if omitted)
--principal, --admin-passwordWhich admin identity to authorise the join
--no-ntpWhen chronyd is already managed by your config management — do not fight over it
--hidden-replicaInstall but keep the replica out of SRV records (useful for standby / backup hosts)
Hidden replica is an underused feature. It participates in replication but is not advertised via DNS SRV, so clients do not pick it up. Ideal for a dedicated backup host or an admin's emergency-console target.

ipa-replica-manage and friends

ipa-replica-manage predates the topology plugin. It still works and is often the fastest way to see what a host thinks is going on locally.

# What does this server replicate with?
sudo ipa-replica-manage list
sudo ipa-replica-manage list ipa1.example.internal

# Push an initial sync from this server to a peer
sudo ipa-replica-manage re-initialize --from=ipa1.example.internal

# Force a sync for a stuck agreement
sudo ipa-replica-manage force-sync --from=ipa1.example.internal

# Remove an agreement (single direction)
sudo ipa-replica-manage del ipa-bad.example.internal

Important: ipa-replica-manage del on its own does not clean the whole topology — it removes agreements on this host only. For full decommissioning, use the topology plugin and ipa server-del:

ipa topologysegment-find realm
ipa topologysegment-del realm ipa1-ipa-bad
ipa server-del ipa-bad.example.internal

Topology segments (the modern way)

# See all segments for the realm suffix
ipa topologysegment-find realm

# Add / remove a segment (this is bidirectional by default)
ipa topologysegment-add realm ipa1-ipa3 \
  --leftnode=ipa1.example.internal --rightnode=ipa3.example.internal

ipa topologysegment-del realm ipa1-ipa3

# Add a one-way segment (rarely useful — only for intentional asymmetry)
ipa topologysegment-add realm ipa1-ipa2-oneway \
  --leftnode=ipa1.example.internal --rightnode=ipa2.example.internal \
  --direction=left-to-right

The topology plugin guards against mistakes: you cannot delete the last segment that keeps the topology connected. If you need to, it refuses until you add an alternative path or explicitly ask for --force.

Visualise

# ASCII-ish
for h in $(ipa server-find --raw | awk '/cn:/ {print $2}'); do
  echo "== $h =="; ipa topologysegment-find realm --server=$h
done

Promoting a replica to CA / KRA

You installed the first replicas without --setup-ca and now you want a second CA. Do not reinstall — promote:

# On the replica, with admin Kerberos ticket
kinit admin
ipa-ca-install --unattended --principal admin --admin-password 'REDACTED'

# Separately, if you also want KRA here:
ipa-kra-install --unattended --principal admin --admin-password 'REDACTED'

After ipa-ca-install finishes, check:

ipa-csreplica-manage list                 # agreements on the ca suffix
ipa topologysegment-find ca
getcert list | head -50                    # certmonger is now tracking CA certs here
Never promote a replica that is behind in replication. Force-sync first (ipa-replica-manage force-sync --from=ipa1), confirm DIRSRV is converged, then install CA. Promoting a stale replica can split the CA's signing history.

Agreement states

A 389-DS replication agreement publishes a status string you can read out of the agreement entry. The states you'll see:

StateMeaningTypical action
INITIATEDAgreement exists; initial online import has not yet started.Wait. If it never progresses, check firewall on 389/636 between the two hosts.
DATA (Replica acquired)Normal: replica caught up to the supplier's max CSN.None.
CONNECTEDReplication session active, actively pushing updates.None.
ERROR (cannot acquire replica)Supplier can't talk to replica or peer is in session with someone else.Usually transient; if persistent, check network and peer load.
ERROR (schema mismatch)Schema changed on one side but hasn't propagated.Force-sync schema, or restart 389-DS on the lagging side.
ERROR (LDAP error 32)Supplier thinks its changelog has been consumed but peer wants entries the supplier already trimmed.Re-initialise (ipa-replica-manage re-initialize --from=...). This is often the first sign of split-brain.
# Read raw agreement status
ldapsearch -Y GSSAPI -b cn=config \
  '(objectclass=nsds5replicationagreement)' \
  dn nsDS5ReplicaHost nsds5replicaLastUpdateStatus nsds5ReplicaUpdateInProgress

Split-brain recovery

Split brain in IPA usually means: a replica was offline long enough for its changelog window to expire, came back, and both sides have diverged changes that can't merge. Symptoms:

Recovery (assumes ipa1 is the authoritative side)

# 1. Stop writes on the diverged side.
ssh ipa2 'sudo ipactl stop'

# 2. Back up just-in-case.
ssh ipa2 'sudo ipa-backup'

# 3. On the authoritative side, mark agreements to the broken peer as halted
#    (avoid corrupt updates while we re-init).
#    Then initiate re-initialisation FROM the authoritative side:
ssh ipa2 'sudo ipactl start'
ssh ipa2 'sudo ipa-replica-manage re-initialize --from=ipa1.example.internal'

# 4. Verify convergence:
kinit admin
ipa user-add sanitycheck-$(date +%s) --first=Sanity --last=Check
# ...on ipa2 a minute later:
ssh ipa2 "ipa user-show sanitycheck-$(date +%s)"

If the split is between CAs (the ca suffix), the equivalent is ipa-csreplica-manage re-initialize --from=ipa1. Do CA re-init before letting clients request new certs, not during.

The 389-DS server ID gotcha

Every IPA server has a replica ID assigned at first install (a small integer baked into its CSN stamps). You cannot change it without reinstall. Practical consequences:

Backup implications

Replication is not a backup. A schema change that deletes a field will happily propagate to every replica. So will a kinit admin; ipa user-del --continue '*'.

Verification

See also: FreeIPA, FreeIPA Dogtag Certs, Kerberos.