Description
chrony reads its sources (server, pool or peer lines) from /etc/chrony/chrony.conf and
the files included by Debian's default configuration: /etc/chrony/conf.d/*.conf and
/etc/chrony/sources.d/*.sources. 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.
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 Debian defaults, which use the Debian NTP pool and the _chrony user.
Applies when
Detected: when: chrony is installed A scanner reports the control not applicable when one is false.
Audit
grep -E '^[[:space:]]*(server|pool|peer)[[:space:]]' /etc/chrony/chrony.conf /etc/chrony/conf.d/*.conf /etc/chrony/sources.d/*.sourcesmust list approved sources.ps -C chronyd -o user=must print_chrony.systemctl is-enabled chronymust printenabledandsystemctl is-active chronyactive.
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
- Add approved sources in
/etc/chrony/sources.d/local.sources, one per line, for exampleserver ntp1.example.org iburst, then runchronyc reload sources. - Remove any
userdirective other thanuser _chronyfrom the chrony configuration and any-uoption fromDAEMON_OPTSin/etc/default/chrony. - Run
systemctl enable --now chrony.
| Restart | none |
| Disruption | none |
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
- chrony.conf(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- chronyd(8), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
Mappings
| Framework | ID | Relation |
|---|---|---|
| NIST SP 800-53 Rev. 55.1.1 | AU-8(1) | partial |
| NIST SP 800-53 Rev. 55.1.1 | AC-6 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
| Taxonomy | ID |
|---|---|
| MITRE ATT&CK | T1070.006 |
Related controls
- related
CB-DEB-SVC-014Run exactly one time synchronization daemon
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Not applicable without chrony; with chrony installed and disabled the enabled, active and user checks fail, fix enables and starts it, audit passes after reboot. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Not applicable without chrony; with chrony installed and disabled the enabled, active and user checks fail, fix enables and starts it, audit passes after reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |