Ubuntu · Services

Configure chrony with time sources, run it unprivileged and keep it running

When it fails: chrony has no time source, runs as root or is not running. The clock is not synchronized, or the NTP daemon parses network traffic with full privileges.

CB-UBU-SVC-016lowactiveautomatedautomated fixprofile core

As released in v0.1.2 (beta). Current state.

Description

chrony reads its sources (server, pool or peer lines) from /etc/chrony/chrony.conf and the files included by Ubuntu's default configuration from 22.04: /etc/chrony/conf.d/*.conf and /etc/chrony/sources.d/*.sources (20.04 only reads chrony.conf). After start-up, chronyd drops root privileges to the _chrony user unless the user directive or the -u option says otherwise. The service chrony.service must be enabled and running.

The sources are site-specific, so the fix only enables and starts the service; adding sources and removing a user root setting are manual. chrony is the default time daemon from 26.04 (version 4.8), which reaches ntp.ubuntu.com with Network Time Security (nts option in /etc/chrony/sources.d/ubuntu-ntp-pools.sources). On 20.04, chrony 3.5 does not support NTS: sources there are authenticated only with symmetric keys, or not at all. Keep NTS when the approved servers support it.

Rationale

Without a source the clock drifts. chronyd parses packets from the network; running it as an unprivileged user limits what a flaw in that code can reach. A stopped daemon leaves the clock unsynchronized.

Impact

None known with the Ubuntu defaults, which use the Ubuntu NTP servers and the _chrony user.

Applies when

Detected: when: chrony is installed A scanner reports the control not applicable when one is false.

Audit

  1. grep -E '^[[:space:]]*(server|pool|peer)[[:space:]]' /etc/chrony/chrony.conf /etc/chrony/conf.d/*.conf /etc/chrony/sources.d/*.sources must list approved sources.
  2. ps -C chronyd -o user= must print _chrony.
  3. systemctl is-enabled chrony must print enabled and systemctl is-active chrony active.

Automated: every check must pass. Scanners report each check by its id.

sources

chrony has at least one server, pool or peer source.

script: |
  o=$(grep -hEs '^[[:space:]]*(server|pool|peer)[[:space:]]' /etc/chrony/chrony.conf \
    /etc/chrony/conf.d/*.conf /etc/chrony/sources.d/*.sources | head -n 5)
  if [ -z "$o" ]; then echo "no server, pool or peer directive"; exit 1; fi
  printf '%s\n' "$o"

user

chronyd runs as _chrony.

script: |
  u=$(ps -C chronyd -o user= 2>/dev/null | sort -u | tr -d ' ' | tr '\n' ' ')
  echo "chronyd user: ${u:-not running}"
  [ "$u" = "_chrony " ]

enabled

chrony is enabled.

unit: chrony.service
state: enabled

active

chrony is running.

script: systemctl is-active chrony.service || exit 1

Remediation

  1. Add approved sources in /etc/chrony/sources.d/local.sources, one per line, for example server ntp1.example.org iburst, then run chronyc reload sources.
  2. Remove any user directive other than user _chrony from the chrony configuration and any -u option from DAEMON_OPTS in /etc/default/chrony.
  3. Run systemctl enable --now chrony.
Restartnone
Disruptionnone

Rollback

Run systemctl disable --now chrony.

enabled

Generated from check enabled: the engine writes the fix for every output, it sets the expected value and the check runs again after.

Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.

References

Mappings

FrameworkIDRelation
NIST SP 800-53 Rev. 55.1.1AU-8(1)partial
NIST SP 800-53 Rev. 55.1.1AC-6related

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

People and lifecycle

Authors
Verified2026-10-19 by Sn0wAlice on 20.04, Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Not applicable on the stock image; with chrony 3.5 installed passes (sources from chrony.conf, chronyd as _chrony), synchronized after reboot.
Verified2026-10-19 by Sn0wAlice on 22.04, Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Not applicable on the stock image; with chrony 4.2 installed passes (sources.d, chronyd as _chrony), synchronized after reboot.
Verified2026-10-19 by Sn0wAlice on 24.04, Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Not applicable on the stock image; with chrony 4.5 installed passes (sources.d, chronyd as _chrony), synchronized after reboot.
Verified2026-10-19 by Sn0wAlice on 26.04, Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Passes on the stock image (chrony 4.8 default, NTS sources in sources.d, chronyd as _chrony).
Introduced inv0.1.0
Created, updated2026-10-19, 2026-10-19
Translationsfr