For decades, Linux administrators used the standard ntpd (Network Time Protocol daemon) to ensure their servers had the correct time. However, as infrastructure moved into the cloud, a massive problem emerged: Virtual Machines can be paused, migrated between physical hosts, or suffer from heavy CPU throttling. This causes their internal clocks to drift wildly. The old ntpd was designed for physical servers with stable hardware clocks and struggles to correct sudden, massive time jumps quickly. To solve this, modern Ubuntu Server uses chrony, a next-generation NTP implementation specifically designed for the chaotic environment of cloud computing and virtual machines.
Why Accurate Time Matters
If your server’s clock is off by even a few minutes (or sometimes just seconds), catastrophic failures occur:
- Authentication fails: Kerberos, Active Directory, and many OAuth systems will instantly reject login attempts if the timestamp on the ticket doesn’t match the server.
- Certificates break: SSL/TLS handshakes will fail if the server thinks an SSL certificate has expired (or hasn’t been issued yet).
- Logs are useless: If you are investigating a security breach across three different servers, and their clocks are not perfectly synchronized, it is impossible to reconstruct the timeline of the attack.
Step 1: Install chrony
On newer Ubuntu releases (20.04 and 22.04), systemd-timesyncd might be the default. For production servers, especially database clusters or domain controllers, you should install chrony instead.
sudo apt update
sudo apt install chrony -y
Installing chrony will automatically disable systemd-timesyncd to prevent conflicts.
Step 2: Configure the NTP Servers
The configuration file is located at /etc/chrony/chrony.conf.
sudo nano /etc/chrony/chrony.conf
Look for the lines starting with pool or server. By default, Ubuntu points to the global ubuntu.pool.ntp.org. If you are running an isolated internal network, you must change this to point to your internal domain controllers or core routers.
# Use your company's internal time servers
server 192.168.1.10 iburst
server 192.168.1.11 iburst
The iburst keyword is crucial. It tells chrony to send a rapid burst of 8 packets when the service first starts, allowing the server to calculate the correct time and synchronize in seconds rather than minutes.
Step 3: Handle Massive Time Jumps (makestep)
Normally, if a server’s clock is wrong, NTP does not just rudely change the time. Instead, it subtly “slews” (speeds up or slows down) the clock tick rate until it catches up. This prevents databases from crashing due to sudden time travel.
However, if a VM is paused for an hour and then resumed, slewing would take days to catch up. chrony uses the makestep directive to handle this.
In chrony.conf, find:
makestep 1 3
This means: “If the time is off by more than 1 second, allow chrony to instantly step (jump) the clock to the correct time, but only allow this to happen during the first 3 clock updates after the service starts.”
Step 4: Restart and Verify
After editing the configuration, restart the service:
sudo systemctl restart chronyd
To verify that chrony is actively synchronizing, use the tracking command:
chronyc tracking
Look at the System time field. It will show you exactly how many seconds (or milliseconds) your server is off from true UTC time. It should be virtually zero.
Step 5: View NTP Sources
To see exactly which upstream servers chrony is talking to, and the quality of the connection (latency and jitter), run:
chronyc sources -v
The server marked with a ^* is the one chrony currently trusts as the absolute source of truth. By implementing chrony, you ensure your Ubuntu Servers maintain cryptographic precision regardless of underlying virtualization quirks.