Skip to main content
RunBook Academy

LinuxXXIV · Time Synchronisationchrony config

chrony client configuration - tuning for accuracy and resilience

Intermediate⏱ ~12 minchronycchronyd

What you'll learn

  • Configure chrony sources for production accuracy
  • Tune makestep for fast initial sync
  • Use drift file and rtcsync for stability
  • Configure NTP authentication for trusted sources

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

A chrony client needs the right sources, the right sync strategy, and the right authentication. This lesson covers each configuration choice and the trade-off it represents.

Sources

chrony accepts two kinds of source:

  • server: a specific host. Use when you know the IP or name and want a single point of contact.
  • pool: a DNS name that resolves to multiple IPs. Use for public NTP pools where you want chrony to choose from multiple servers.
# Single server (specific host)
server ntp1.example.com iburst

# Multiple specific servers
server ntp1.example.com iburst
server ntp2.example.com iburst

# Pool (DNS name with multiple A records)
pool time.cloudflare.com iburst maxsources 4

The iburst option speeds up the initial sync: instead of one packet, chrony sends a burst of up to 8 packets. This makes the first sync complete in seconds rather than minutes. It is the right choice for almost every configuration.

The maxsources option (for pool) limits how many sources chrony considers. Four is a good default.

prefer

server ntp1.example.com iburst prefer
server ntp2.example.com iburst

prefer makes this source the preferred choice when multiple sources agree. Use it for the most accurate source or the most trusted source (the company NTP server, for example).

makestep

makestep 1.0 3

makestep takes two mandatory parameters: a threshold in seconds and a limit on the number of clock updates. It tells chronyd to step (jump) the clock when the correction is larger than the threshold, but only while fewer than limit updates have happened since chronyd started. There are no built-in values: without the directive, chrony never steps, it only slews (gradually adjusts), which can take hours to close a large offset.

makestep 1.0 3 is therefore not a default — it is the convention every distribution ships. It means “step if the correction exceeds 1 second, but only on the first three updates”, which in practice means “step at boot, slew forever after”.

Common configurations:

  • makestep 1.0 3: step if >1 second, on the first three updates only. The safe production choice.
  • makestep 0.1 3: same shape, tighter threshold. Use when a host must be accurate within 100 ms very quickly after boot.
  • Omit the directive entirely: never step, only slew. That is chrony’s built-in behaviour, so there is nothing to write.

There is no way to “turn makestep off after ten minutes” from the config file, and writing two makestep lines does not do it — the last line silently wins. The update limit is the mechanism: makestep 1.0 3 already confines stepping to the first few updates after start.

To correct a large offset once, at a moment you choose, use the runtime command instead of changing the config:

sudo chronyc makestep

rtcsync

rtcsync

The rtcsync directive tells chrony to sync the system clock to the hardware clock (RTC) every 11 minutes. This keeps the RTC accurate, so on reboot the system clock is close to correct even if NTP is unreachable.

Without rtcsync, the RTC drifts from true time. After a long downtime, the host boots with a clock far from true.

driftfile

driftfile /var/lib/chrony/drift

The drift file records the system’s clock frequency error (in ppm). On restart, chrony reads this and applies the correction immediately. Without it, chrony has to relearn the drift, which takes minutes.

The file is updated whenever chrony has enough samples to estimate the drift. On a healthy host, the file is updated daily.

chrony on VMs

Virtual machines have unusual clock behaviour. The guest clock may pause when the VM is paused, snapshotted or migrated, then resume far behind true time.

The wrong answer is to reach for makestep 0.1 -1 so the guest can step at any time. That trades a rare, visible resume gap for a permanent licence to jump the clock backwards under any transient network wobble.

The right answer is to give the guest a source it can trust and keep the conservative stepping policy:

# Prefer the hypervisor's own clock source where available.
# KVM/QEMU guests with ptp_kvm loaded expose /dev/ptp0,
# which tracks the host clock directly.
refclock PHC /dev/ptp0 poll 2 dpoll -2 offset 0

# Public or internal NTP as the cross-check
pool time.cloudflare.com iburst maxsources 4

# Step only during the first few updates after chronyd starts
makestep 1.0 3

rtcsync

Check the guest actually has a PTP device before using that refclock line:

ls -l /dev/ptp*
sudo modprobe ptp_kvm

If there is no /dev/ptp0, drop the refclock line and rely on NTP alone. On VMware guests, disable the VMware Tools time synchronisation rather than running it alongside chrony — two things stepping the same clock fight each other.

After a resume or a snapshot restore, correct the offset deliberately rather than leaving stepping permanently enabled:

sudo chronyc makestep
chronyc tracking

NTP authentication

For trusted NTP sources, use authentication to prevent spoofing.

On chrony 4.0 and later, prefer NTS (Network Time Security, RFC 8915). It uses TLS to establish keys, so there is no shared secret to distribute or rotate:

server ntp1.example.com iburst nts

Check it is actually authenticating, not silently falling back:

chronyc -N authdata

The KeyID, Type and KLen columns are populated for an NTS-protected source. A blank row means the source is unauthenticated.

Symmetric keys remain useful for older servers. Generate the key first:

sudo sh -c 'chronyc keygen 1 SHA256 128 >> /etc/chrony/chrony.keys'
sudo chmod 600 /etc/chrony/chrony.keys

Then reference it on the source line:

keyfile /etc/chrony/chrony.keys
server ntp1.example.com iburst key 1 trust require

The server must be configured with the same key ID and key. For production deployments, authentication prevents attackers from poisoning your clocks.

Logging

logdir /var/log/chrony
log measurements statistics tracking

The measurements, statistics, and tracking log directives write detailed data to files. Use for offline analysis:

chronyc tracking -v

Output includes more detail than the standard tracking output.

Common production configuration

# Drift file
driftfile /var/lib/chrony/drift

# NTP sources
pool time.cloudflare.com iburst maxsources 4
server ntp1.example.com iburst prefer

# Step only on the first three updates after chronyd starts,
# i.e. at boot. After that the update limit is spent and
# chrony slews. Never use a negative limit here.
makestep 1.0 3

# Sync the RTC
rtcsync

# Logging
logdir /var/log/chrony
log measurements statistics tracking

# Allow this host to serve NTP if requested
# allow 10.0.0.0/24

Apply and verify:

sudo systemctl restart chronyd
sleep 30
chronyc tracking
chronyc sources

The tracking output should show <1 ms offset within a few minutes. If not, check sources for unreachable servers.

Verify after reboot

sudo reboot
# After reboot
chronyc tracking
chronyc sources -v

The clock should be within milliseconds of true time within 30 seconds of boot. If it is not:

  • makestep may be misconfigured.
  • Sources may be unreachable.
  • The drift file may be missing.

Knowledge check

Knowledge check · 5 questions

  1. Q1. What does the iburst option do in a chrony source directive?

  2. Q2. rtcsync is required for chrony to work.

  3. Q3. Which of the following are valid chrony source directives? Select all that apply.

  4. Q4. A colleague pushes `makestep 0.1 -1` to every node of a Pacemaker cluster to "keep the clocks tight". What is the operational consequence?

  5. Q5. You add `trust 1` on its own line under a `server ntp1.example.com key 1` line and restart chronyd. What happens?

Passing score: 75%. Answers are checked in this browser.