On Linux servers, accurate system time is important for log chronology, authentication, certificate validity periods, and comparing events across multiple systems.
On RHEL 8, chrony can be used for time synchronization. The chronyd daemon can be managed with systemctl, and synchronization status can be checked with chronyc.
- Red Hat Enterprise Linux 8 - Configuring time synchronization
- chrony 4.4 chronyc manual
- chrony 4.4 chrony.conf manual
In this article, we install chrony, configure an NTP server persistently, and then use waitsync, sources, and tracking to determine whether a problem lies in the configuration, reachability, time source selection, or system clock synchronization.
Variable notation
Section titled “Variable notation”Values that need to be changed for each environment are represented by the following variable.
| Variable name | Example setting | Description |
|---|---|---|
<<NTP_SERVER>> | time.cloudflare.com | Hostname of the NTP server used as the synchronization target |
This configuration example uses Cloudflare’s public NTP service. Cloudflare identifies time.cloudflare.com as the endpoint for its NTP service.
If your organization specifies a particular NTP server, replace <<NTP_SERVER>> with its hostname.
Step 1: Install chrony
Section titled “Step 1: Install chrony”Install the chrony package.
sudo dnf install -y chronyNext, start chronyd and configure it to start automatically when the operating system boots.
sudo systemctl enable --now chronydVerify that the service is running and automatic startup is enabled.
sudo systemctl status chronyd --no-pagersudo systemctl is-enabled chronydIf systemctl status shows active (running) and systemctl is-enabled shows enabled, the chrony service is running and automatic startup is enabled.
Step 2: Configure the NTP server persistently
Section titled “Step 2: Configure the NTP server persistently”The chrony server directive lets you specify an NTP server. The iburst option sends the initial queries to the time source at short intervals so that initial measurements can be collected more quickly.
For details, refer to the official chrony configuration file manual.
Here, the existing /etc/chrony.conf is backed up once, and the specified NTP server is added only if it is not already configured.
if [ ! -e /etc/chrony.conf.before-ntp ]; then sudo cp -a /etc/chrony.conf /etc/chrony.conf.before-ntpfi
if ! sudo grep -Fqx 'server <<NTP_SERVER>> iburst' /etc/chrony.conf; then printf '%s\n' 'server <<NTP_SERVER>> iburst' | sudo tee -a /etc/chrony.conf >/dev/nullfi
sudo grep -F 'server <<NTP_SERVER>> iburst' /etc/chrony.confThis procedure does not automatically remove existing server or pool settings. If time sources must be restricted in the actual environment, organize the existing configuration according to your organization’s NTP design.
Restart chronyd to apply the configuration. Then verify that the service is running, the specified configuration remains in the file, and chronyd recognizes the specified time source.
sudo systemctl restart chronydsudo systemctl is-active chronydsudo grep -F 'server <<NTP_SERVER>> iburst' /etc/chrony.confsudo chronyc -N sources | grep -F '<<NTP_SERVER>>'If is-active shows active and both the configuration line and <<NTP_SERVER>> can be confirmed, the time source configuration has been saved to the file and is still loaded after restarting chronyd.
Step 3: Wait for synchronization with waitsync
Section titled “Step 3: Wait for synchronization with waitsync”Even after configuring the NTP server and restarting chronyd, the system is not necessarily synchronized immediately. chronyd performs measurements against the time source and determines whether it can be used for synchronization.
chronyc waitsync waits until chronyd is synchronized. The official chrony 4.4 manual defines the following syntax:
waitsync [max-tries [max-correction [max-skew [interval]]]]
The first argument is the maximum number of attempts, the second is the allowed remaining time correction, the third is the allowed skew, and the fourth is the check interval. If the second or third argument is set to 0, no limit is applied for that value.
Here, synchronization is awaited for up to 60 attempts at 2-second intervals.
sudo chronyc waitsync 60 0 0 2If the command exits successfully, chronyd is synchronized with an available time source. If synchronization cannot be established within the maximum number of attempts, the command exits with a nonzero status. In that case, use sources and tracking to investigate the cause.
Step 4: Check time source status and reachability with sources
Section titled “Step 4: Check time source status and reachability with sources”chronyc sources lets you check the selection status, reachability, and measurement status of each time source referenced by chronyd. Adding -v displays explanations of the columns, while -N displays the original name instead of the address after name resolution.
Display detailed information about the specified time source and verify that responses are being received.
sudo chronyc -N sources -vsudo chronyc -N sources | awk -v host='<<NTP_SERVER>>' ' $2 == host { found = 1 reach = $5 + 0 if (reach > 0) { reachable = 1 } } END { exit !(found && reachable) }'In sources, check the following items in particular:
^in theMcolumn indicates an NTP server.*in theScolumn indicates the currently selected time source.+in theScolumn indicates a time source being used together with the selected source.?in theScolumn indicates that no measurements suitable for selection are available.Reachshows the response history for recent NTP requests as an 8-bit octal value.LastRxshows the time elapsed since the last valid measurement was received.
The verification command above exits successfully only when <<NTP_SERVER>> exists in sources and Reach is greater than 0. This confirms that chronyd recognizes the configured time source and has received at least one NTP response.
If <<NTP_SERVER>> is displayed but Reach remains 0, the configuration itself may be recognized even though NTP communication is not succeeding. Check DNS resolution, the network path for UDP/123, network-side filtering, and whether the NTP server is responding.
Step 5: Check system clock synchronization status with tracking
Section titled “Step 5: Check system clock synchronization status with tracking”While sources shows the state of individual time sources, tracking lets you check the overall synchronization state of the system clock managed by chronyd.
Display synchronization information and check the reference, stratum, time difference, and synchronization status.
tracking="$(sudo chronyc tracking)"printf '%s\n' "$tracking"printf '%s\n' "$tracking" | grep -F 'Reference ID'printf '%s\n' "$tracking" | grep -F 'System time'printf '%s\n' "$tracking" | grep -F 'Leap status' | grep -F 'Normal'printf '%s\n' "$tracking" | awk -F: ' /^[[:space:]]*Stratum[[:space:]]*:/ { value = $2 + 0 found = 1 if (value > 0) { ok = 1 } } END { exit !(found && ok) }'Check the following fields in particular:
Reference ID: currently referenced time sourceStratum: NTP stratum of the local systemSystem time: remaining difference between the system clock and NTP timeLast offset: offset estimated during the last clock updateRMS offset: RMS value of the offsetsSkew: error range of the frequency estimateRoot delay: cumulative delay to the reference time sourceRoot dispersion: estimated error relative to the reference timeLeap status: leap-second and synchronization status
This check verifies that Stratum is greater than 0 and that Leap status is Normal. Because System time is also displayed, you can check not only synchronization status but also the currently remaining time difference.
Step 6: Combine sources and tracking to isolate the problem
Section titled “Step 6: Combine sources and tracking to isolate the problem”Finally, combine sources and tracking.
Receiving responses from the specified NTP server in sources and having the local system in a synchronized state in tracking are separate checks. Checking both together lets you distinguish between time source reachability and system clock synchronization.
sources="$(sudo chronyc -N sources)"tracking="$(sudo chronyc tracking)"
printf '%s\n' "$sources"printf '%s\n' "$tracking"
printf '%s\n' "$sources" | awk -v host='<<NTP_SERVER>>' ' $2 == host { found = 1 reach = $5 + 0 if (reach > 0) { reachable = 1 } } END { exit !(found && reachable) }'
printf '%s\n' "$tracking" | grep -F 'Leap status' | grep -F 'Normal'If this check exits successfully, both of the following conditions are true:
- NTP responses are being received from
<<NTP_SERVER>>. - The local system clock is synchronized.
The results can be interpreted as follows:
| sources | tracking | Main areas to check |
|---|---|---|
| Target server is not displayed | Not synchronized | Contents of /etc/chrony.conf, whether the configuration was applied, hostname specification |
Target server is displayed but Reach is 0 | Not synchronized | DNS, UDP/123, network path, NTP server response |
Reach is greater than 0 but the source is not selected | Not synchronized or synchronized to another time source | State of the S column, measurement status, comparison with other time sources |
Reach is greater than 0 | Leap status: Normal | NTP reachability and system clock synchronization are established |
Summary
Section titled “Summary”With chrony time synchronization, it is not sufficient to determine that everything is working solely because chronyd is running.
First, configure the time source persistently in /etc/chrony.conf and verify that chronyd still recognizes the setting after a restart. Then use waitsync to wait for synchronization, use sources to check the time source selection state, Reach, and measurement status, and use tracking to check the reference, stratum, system time difference, and synchronization status.
When investigating time drift, checking the configuration, time source reachability, time source selection, and system clock synchronization separately makes it easier to identify the stage at which the problem is occurring.