--- 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.