---
myst:
html_meta:
description: Set up a secondary Key Distribution Center (KDC) for high availability and redundancy in your Kerberos infrastructure.
---
(set-up-secondary-kdc)=
# How to set up secondary KDC
Once you have one Key Distribution Center (KDC) on your network, it is good practice to have a secondary KDC in case the primary becomes unavailable.
Also, if you have Kerberos clients that are on different networks (possibly separated by routers using NAT), it is wise to place a secondary KDC in each of those networks.
```{note}
The native replication mechanism explained here relies on a cron job; it essentially dumps the DB on the primary and loads it back up on the secondary. You may want to take a look at using the `kldap` backend, which can use the OpenLDAP replication mechanism. This is explained further below.
```
## Install the required packages
First, install the packages, and when asked for the Kerberos and Admin server names enter the name of the Primary KDC:
```bash
sudo apt install krb5-kdc krb5-admin-server
```
Once you have installed the packages, create the host principals for both KDCs. From a terminal prompt, enter:
```bash
$ kadmin -q "addprinc -randkey host/kdc01.example.com"
$ kadmin -q "addprinc -randkey host/kdc02.example.com"
```
```{note}
The `kadmin` command defaults to using a principal like `username/admin@EXAMPLE.COM`, where `username` is your current shell user. If you need to override that, use `-p `.
```
Extract the **key file** for the `kdc02` principal, which is the server we are on:
```bash
$ sudo kadmin -p ubuntu/admin -q "ktadd host/kdc02.example.com"
```
Next, there needs to be a `kpropd.acl` file on each KDC that lists all KDCs for the realm. For example, on both the **primary and secondary KDC**, create `/etc/krb5kdc/kpropd.acl`:
```text
host/kdc01.example.com@EXAMPLE.COM
host/kdc02.example.com@EXAMPLE.COM
```
```{note}
It's customary to allow both KDCs because one may want to switch their roles if one goes bad. For such an eventuality, both are already listed here.
```
Create an empty database on the **secondary KDC**:
```bash
$ sudo kdb5_util create -s
```
Now install `kpropd` daemon, which listens for connections from the `kprop` utility from the **primary KDC**:
```bash
$ sudo apt install krb5-kpropd
```
The service will be running immediately after installation.
From a terminal on the **primary KDC**, create a dump file of the principal database:
```bash
$ sudo kdb5_util dump /var/lib/krb5kdc/dump
```
Still on the **Primary KDC**, extract its **key**:
```bash
$ sudo kadmin.local -q "ktadd host/kdc01.example.com"
```
On the **primary KDC**, run the `kprop` utility to push the database dump made before to the secondary KDC:
```bash
$ sudo kprop -r EXAMPLE.COM -f /var/lib/krb5kdc/dump kdc02.example.com
Database propagation to kdc02.example.com: SUCCEEDED
```
Note the `SUCCEEDED` message, which signals that the propagation worked. If there is an error message, check `/var/log/syslog` on the secondary KDC for more information.
You may also want to create a cron job to periodically update the database on the **secondary KDC**. For example, the following will push the database every hour:
```bash
# m h dom mon dow command
0 * * * * root /usr/sbin/kdb5_util dump /var/lib/krb5kdc/dump && /usr/sbin/kprop -r EXAMPLE.COM -f /var/lib/krb5kdc/dump kdc02.example.com
```
Finally, start the `krb5-kdc` daemon on the **secondary KDC**:
```bash
$ sudo systemctl start krb5-kdc.service
```
```{note}
The secondary KDC does not run an admin server, since it's a read-only copy.
```
From now on, you can specify both KDC servers in `/etc/krb5.conf` for the `EXAMPLE.COM` realm, in any host participating in this realm (including `kdc01` and `kdc02`), but remember that there can only be one admin server and that's the one running on `kdc01`:
```text
[realms]
EXAMPLE.COM = {
kdc = kdc01.example.com
kdc = kdc02.example.com
admin_server = kdc01.example.com
}
```
The **secondary KDC** should now be able to issue tickets for the realm. You can test this by stopping the `krb5-kdc` daemon on the primary KDC, then using `kinit` to request a ticket. If all goes well you should receive a ticket from the secondary KDC. Otherwise, check `/var/log/syslog` and `/var/log/auth.log` on the secondary KDC.