The two infrastructure prerequisites that most often break Kerberos: unsynchronized time and unprepared DNS. This episode sets up time synchronization with chrony, clockskew configuration, SRV records for KDC discovery, host fallbacks, and troubleshooting the legendary clock skew error.

In episode 3 you saw the full Kerberos authentication flow — and two things stood out as the foundation of all those flows: the timestamp that feeds the authenticator, and the name resolution that lets a client find the KDC. Episode 3 closed with a warning that time synchronization is part of Kerberos's security mechanism itself. Now it's time to prove it.
This episode dissects the two infrastructure prerequisites that most often break real-world Kerberos implementations: time synchronization and DNS. You'll set up NTP with chrony, understand the 5-minute clock tolerance and how to adjust it, create SRV records for KDC discovery, prepare a /etc/hosts fallback, and learn to solve the legendary Clock skew too great error. Let's start with the most critical: time.
Recall the mechanism from episode 3: the authenticator contains a timestamp encrypted with the session key, and the server stores that timestamp in a replay cache. Both only make sense if all parties share the same understanding of time.
The timestamp has two functions:
Without clock synchronization, these functions collapse. A slow client clock makes timestamps always "in the past," so valid requests get rejected. A client clock that's too fast makes timestamps "from the future," which is also suspected. Both conditions surface as the same error message.
Kerberos has a built-in tolerance of 300 seconds (5 minutes) — the default clockskew value. That means the clock difference between client, KDC, and service can be up to 5 minutes. This is loose enough to accommodate normal clock drift, but tight enough to prevent replay attacks with an unreasonable window.
When the clock difference exceeds the tolerance, the KDC or service responds with a classic error:
kinit: Preauthentication failed while getting initial credentialsClock skew too great (37 seconds)The number in parentheses hints at the size of the difference. Note that the error can surface as Preauthentication failed — meaning debugging needs a deeper trace. The fastest way to find out: run KRB5_TRACE=1 kinit in your lab.
We'll use chrony — a modern NTP implementation available on Ubuntu Server. Install it on all three VMs (the KDC and both clients):
sudo apt update
sudo apt install chrony -yIn a lab environment, all VMs can point to the same time source — for example, a public NTP server or a VM acting as the time server. The default configuration in /etc/chrony/chrony.conf already points to the public NTP pool:
# Use public servers from the pool.ntp.org project.
pool 2.ubuntu.pool.ntp.org iburstFor an isolated lab, you can add an internal time server. Enable and verify:
sudo systemctl enable --now chrony
chronyc tracking
timedatectlThe chronyc tracking output shows the synchronization status: the System time field shows the difference between the system clock and the time source. If all VMs are synchronized to the same source, the difference between VMs will be tiny — far below the 5-minute tolerance.
Tip
A professional habit: before any Kerberos practice, run chronyc tracking on every VM and make sure none is left behind. A single VM whose clock is off by 6 minutes is enough to trigger a Clock skew too great error that makes all other practice feel wasted. Prevention is always cheaper than debugging.
The 5-minute tolerance is the default, but it can be changed through the /etc/krb5.conf file. In the [libdefaults] section, add the clockskew value in seconds:
[libdefaults]
default_realm = EXAMPLE.COM
clockskew = 300
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = trueThe value 300 equals the default, but writing it explicitly makes your configuration clear and easy to adjust. In practice, careful admins sometimes increase this value in environments where the clock is hard to maintain — but be careful: the larger the tolerance, the wider the replay attack window you allow.
DNS is how a client finds the KDC. Without correct DNS, the client will never find the server it needs to talk to — even if the time is perfect.
Kerberos depends heavily on names:
Service principals use hostnames like host/kdc.example.com@EXAMPLE.COM, and the service needs to validate that the client is contacting the correct name. Inconsistent DNS — a hostname that differs from the DNS record, or a mismatched reverse lookup — is a source of Server not found in Kerberos database errors.
To find the KDC, clients read SRV records in the realm's DNS zone. The three main records that must exist:
| SRV Record | Port | Purpose |
|---|---|---|
_kerberos._udp.example.com | 88 | KDC discovery (UDP) |
_kerberos._tcp.example.com | 88 | KDC discovery (TCP) |
_kerberos-master._tcp.example.com | 88 | Master KDC (optional) |
_kpasswd._udp.example.com | 464 | Password change service |
Example in a BIND zone (db.example.com):
$ORIGIN example.com.
_kerberos._udp SRV 0 0 88 kdc.example.com.
_kerberos._tcp SRV 0 0 88 kdc.example.com.
_kerberos-master._tcp SRV 0 0 88 kdc.example.com.
_kpasswd._udp SRV 0 0 464 kdc.example.com.One more TXT record helps clients learn which realm matches a domain:
$ORIGIN example.com.
_kerberos.example.com. TXT "EXAMPLE.COM"After creating the records, verify with dig:
dig +short _kerberos._udp.example.com SRV
dig +short -x 192.168.10.10
dig +short _kerberos.example.com TXTIf dig +short _kerberos._udp.example.com SRV returns 0 0 88 kdc.example.com., clients will find the KDC correctly. You can also test client resolution directly with getent hosts kdc.example.com.
For small labs or environments without full DNS, Kerberos can use /etc/hosts as a fallback. On every VM, add the following lines:
192.168.10.10 kdc.example.com kdc
192.168.10.21 client1.example.com client1
192.168.10.22 client2.example.com client2Note
/etc/hosts resolves forward lookups, but not SRV records — so the client still needs to know where the KDC is, which can be pointed to via the kdc = ... line in the [realms] section of /etc/krb5.conf. For a learning lab, the combination of /etc/hosts plus the kdc directive in krb5.conf is sufficient and avoids BIND complexity.
When the error appears, use the following check sequence:
| Step | Command | What it checks |
|---|---|---|
| 1 | timedatectl status | System clock and timezone of all VMs |
| 2 | chronyc tracking | Clock difference against the time source |
| 3 | KRB5_TRACE=1 kinit | Detailed trace; look for the clock skew message |
| 4 | date on all VMs | Comparing clocks between hosts |
date --set="2026-08-03 10:00:00"If a large difference is found, fix the system clock — in a lab it's often enough to rewrite the clock with date --set, then let chrony maintain consistency afterward. In production, fix the NTP source and let synchronization work automatically.
This episode handled the two infrastructure prerequisites that most often destroy Kerberos: time synchronization and DNS. You set up chrony on all VMs, understood the 5-minute clockskew tolerance and how to change it in krb5.conf, created the _kerberos, _kerberos-master, and _kpasswd SRV records along with the realm TXT record, used /etc/hosts as a lab fallback, and learned the troubleshooting sequence for the Clock skew too great error.
Key points to take with you:
dig is the fastest DNS verification tool; /etc/hosts is the small-lab lifesaver.Clock skew too great error usually hides behind Preauthentication failed — dig it out with KRB5_TRACE=1.In the next episode, episode 5, we'll assemble everything: installing the MIT Kerberos KDC — from package installation, realm configuration in krb5.conf and kdc.conf, creating the database with kdb5_util, creating the first principal, to verifying with kinit and klist. This is the episode where your lab truly comes alive. See you there!