Time to assemble the lab into a living Kerberos kingdom. This episode guides you through installing the MIT Kerberos KDC, configuring the realm in krb5.conf and kdc.conf, creating the database with kdb5_util, creating the first principal via kadmin.local, and verifying with kinit and klist.

In episode 4 you prepared Kerberos's two infrastructure prerequisites: time synchronized via chrony and DNS ready to discover the KDC. Now all those foundations will be tested in the real world. This episode is the most satisfying moment in the lab: installing the MIT Kerberos KDC and watching the EXAMPLE.COM realm truly come alive.
We'll install the Kerberos packages, lay out the realm configuration in two important files (/etc/krb5.conf and /etc/krb5kdc/kdc.conf), create the KDC database with kdb5_util, start the krb5-kdc and krb5-admin-server services, create the first principal via kadmin.local, then prove everything works with kinit and klist. After this episode, you'll have your own authentication kingdom.
Before installing, choose your implementation. There are two main open-source Kerberos implementations:
| Implementation | Notes |
|---|---|
| MIT Kerberos | The reference implementation, most widely used and documented |
| Heimdal | A valid alternative; some differences in tools and paths |
For this series we consistently use MIT Kerberos because it dominates the documentation, ecosystem, and configuration paths you'll encounter in the working world. This choice was already settled in episode 0.
On the KDC server (kdc.example.com), install two core packages: krb5-kdc and krb5-admin-server. On clients, krb5-user is enough — it contains the kinit, klist, and kdestroy tools.
sudo apt update
sudo apt install krb5-kdc krb5-admin-server -yNote
During installation on Debian/Ubuntu, you'll be asked for the realm name and KDC server. If you answer correctly (realm EXAMPLE.COM, server kdc.example.com), that part is automatically filled into /etc/krb5.conf. If unsure, leave the defaults and fix them in the config file — we'll write it explicitly in a moment.
There are two ways to create a realm: using the interactive krb5_newrealm script, or writing the configuration manually. To understand what happens behind the scenes, we choose manual.
This file governs client Kerberos behavior — every host in the realm needs it, including clients. Its minimal contents:
[libdefaults]
default_realm = EXAMPLE.COM
clockskew = 300
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
EXAMPLE.COM = {
kdc = kdc.example.com
admin_server = kdc.example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
[logging]
default = SYSLOG:INFO:LOCAL0[realms] tells the client where the KDC and admin server are; [domain_realm] maps domains to realms. If DNS isn't fully set up, the kdc line here becomes the deciding factor for KDC discovery.
This file governs the server-side KDC behavior — it only exists on the KDC machine. On Debian/Ubuntu its location is /etc/krb5kdc/kdc.conf; on the RHEL family it's /var/kerberos/krb5kdc/kdc.conf:
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
EXAMPLE.COM = {
database_name = /var/lib/krb5kdc/principal
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
acl_file = /etc/krb5kdc/kadm5.acl
key_stash_file = /etc/krb5kdc/stash
max_life = 10h 0m 0s
max_renewable_life = 7d 0h 0m 0s
master_key_type = aes256-cts
supported_enctypes = aes256-cts:normal aes128-cts:normal
}An important note: the supported_enctypes above is deliberately restricted to AES only — DES and 3DES have long been considered weak and must not be used. This is a practice we'll explore further in episode 11.
The database stores all principals and their keys. Create it with kdb5_util:
sudo kdb5_util create -sThis command will prompt for a master password — the secret key protecting the entire database. Don't forget this password; losing it means losing access to the entire realm. The -s option creates a stash file (/etc/krb5kdc/stash), a copy of the master key that lets the KDC read the database automatically at boot, without waiting for human input.
Loading random data
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.COM',
master key name 'K/M@EXAMPLE.COM'
You will be prompted for the database Master Password.Warning
The stash file stores the master key as a file — if stolen, the entire realm can be compromised. Protect it with strict permissions (sudo chmod 600 /etc/krb5kdc/stash) and understand that KDC security is realm security, because the KDC is the single point of trust in the entire Kerberos design.
Two services must run: krb5-kdc (serving port 88) and krb5-admin-server (serving port 749 for kadmin). Enable and start both:
sudo systemctl enable --now krb5-kdc krb5-admin-serversystemctl status krb5-kdc krb5-admin-serverMake sure both show active (running). Don't forget the firewall: allow port 88 (TCP and UDP) for the KDC and 749 (TCP) for kadmin.
The first principal is created via kadmin.local — the administration tool that runs directly on the KDC machine and doesn't require network authentication (because it already runs as root). Create an admin principal and a user principal:
sudo kadmin.local
kadmin.local: addprinc admin/admin
kadmin.local: addprinc arman
kadmin.local: listprincs
kadmin.local: quitaddprinc admin/admin creates a principal with full administrative rights — we need to authorize it through the ACL file /etc/krb5kdc/kadm5.acl:
*/admin@EXAMPLE.COM *This line grants full administrative access (the asterisk) to all principals with the admin instance in the EXAMPLE.COM realm. With this ACL, remote kadmin (not kadmin.local) can be used from clients — a topic we'll cover in episode 8.
All the components are standing. Now test from a client (client1.example.com) — this is the moment of truth:
kinit armanEnter the password you just created for the arman principal, then view the ticket obtained:
klistTicket cache: FILE:/tmp/krb5cc_1000
Default principal: arman@EXAMPLE.COM
Valid starting Expires Service principal
08/03/2026 09:00:00 08/03/2026 19:00:00 krbtgt/EXAMPLE.COM@EXAMPLE.COMThe ticket with the service principal krbtgt/EXAMPLE.COM@EXAMPLE.COM is a TGT — proof that the entire AS-REQ/AS-REP flow from episode 3 works, from kinit to klist. You now officially have a living Kerberos realm.
Tip
After enjoying your first ticket, clear it with kdestroy and check again with klist. This sequential kinit, klist, kdestroy habit is the ticket lifecycle you'll repeat throughout your Kerberos management career — understand and memorize the rhythm now.
| Step | Command / File |
|---|---|
| Install packages | krb5-kdc, krb5-admin-server, krb5-user |
| Client configuration | /etc/krb5.conf |
| Server configuration | /etc/krb5kdc/kdc.conf |
| Create database | sudo kdb5_util create -s |
| Start services | systemctl enable --now krb5-kdc krb5-admin-server |
| Create principals | sudo kadmin.local then addprinc |
| Authorize admin | /etc/krb5kdc/kadm5.acl |
| Verify | kinit arman, klist, kdestroy |
This episode transformed your lab from three VMs into a working Kerberos realm. You installed MIT Kerberos, laid out /etc/krb5.conf and /etc/krb5kdc/kdc.conf, created the database with kdb5_util create -s (complete with the stash file), started krb5-kdc and krb5-admin-server, created the first principal via kadmin.local, then proved everything with kinit, klist, and kdestroy.
Key points to take with you:
krb5-kdc + krb5-admin-server./etc/krb5.conf governs the client, /etc/krb5kdc/kdc.conf governs the server.kdb5_util create -s creates the database + stash; the master password must be stored safely.kadmin.local creates principals without network authentication; the kadm5.acl ACL governs admin rights.krbtgt/EXAMPLE.COM@EXAMPLE.COM in klist) is tangible proof the Kerberos flow works.In the next episode, episode 6, we'll configure the Kerberos client in full — explore every section of /etc/krb5.conf, create user principals with password policies, and dissect the credential cache (FILE vs KEYRING) that determines where and how your tickets are stored. Your kingdom is standing; now it's time to strengthen the palace. See you there!