Last updated: 2026-05-15
Chrony NTS Configuration Guide
This guide provides recommended Network Time Security (NTS) settings for chrony. NTS is a cryptographic extension to NTP that authenticates time synchronization using TLS, preventing man-in-the-middle attacks on time data. Chrony has supported NTS since version 4.0.
Prerequisites
- Chrony 4.0 or later (4.1+ recommended; see version notes below). RHEL 8.0--8.3 ships chrony 3.5 (no NTS); upgrade to RHEL 8.4+ for chrony 4.x. SLES 15 SP1--SP3 also ships chrony 3.x.
- GnuTLS or OpenSSL library (chrony's NTS-KE uses TLS 1.3)
- A valid TLS certificate and private key (for server mode)
- Network access to port 4460 (NTS-KE) and port 123 (NTP)
Path note: This guide uses RHEL/CentOS paths (
/etc/chrony.conf). On Debian/Ubuntu, the config file is/etc/chrony/chrony.confand the chrony user/group is_chrony(with underscore) instead ofchrony.
NTS Overview
NTS works in two phases:
- NTS-KE (Key Establishment) -- A TLS 1.3 handshake on port 4460 authenticates the server and establishes shared keys
- NTP with cookies -- Subsequent NTP packets on port 123 carry encrypted cookies and authentication extensions derived from the NTS-KE session
Client Configuration
Basic NTS Client
Enable NTS for upstream time servers by adding the nts keyword:
# /etc/chrony.conf
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts
server ntppool1.time.nl iburst nts
NTS-KE Port
If a server uses a non-standard NTS-KE port:
server nts.example.com iburst nts ntsport 4461
Certificate Trust Store
Chrony uses the system trust store by default. To specify a custom CA bundle:
# RHEL/CentOS:
ntstrustedcerts /etc/pki/tls/certs/ca-bundle.crt
# Debian/Ubuntu: /etc/ssl/certs/ca-certificates.crt
# SLES: /etc/ssl/ca-bundle.pem
NTS Cookie Storage
Persist NTS cookies across restarts to avoid repeated NTS-KE handshakes:
ntsdumpdir /var/lib/chrony
Rate Limiting NTS-KE
Limit how often chrony retries NTS-KE on failure:
ntsrefresh 86400
Version note:
ntsrefreshrequires chrony 4.1+. On chrony 4.0 (Debian 11), omit this directive.
This sets the maximum interval (in seconds) between NTS-KE requests to a server.
Server Configuration
NTS-KE Server
Configure chrony as an NTS-capable NTP server:
# /etc/chrony.conf
# NTS-KE server settings
ntsserverkey /etc/chrony/ssl/privkey.pem
ntsservercert /etc/chrony/ssl/fullchain.pem
The certificate must be valid for the server's hostname. Let's Encrypt certificates work well.
NTS-KE Port
By default, chrony listens on port 4460 for NTS-KE. To change it:
ntsport 4460
Key Rotation
NTS uses server cookies encrypted with a key that chrony rotates automatically. Persist the keys across restarts:
ntsdumpdir /var/lib/chrony
Chrony generates new cookie keys automatically and retains old keys long enough for clients to transition.
NTS Process Separation
For security, run the NTS-KE helper as a separate unprivileged process:
ntsprocesses 1
Version note:
ntsprocessesrequires chrony 4.1+. On chrony 4.0 (Debian 11), omit this directive — NTS-KE will run in the main process instead.
Complete Client Configuration
# /etc/chrony.conf
# NTS-authenticated time sources
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts
server ntppool1.time.nl iburst nts
# Fallback (unauthenticated) sources
pool pool.ntp.org iburst maxsources 2
# NTS cookie storage
ntsdumpdir /var/lib/chrony
# Allow system clock to be stepped on first sync
makestep 1.0 3
# Record tracking data
driftfile /var/lib/chrony/drift
# RTC synchronization
rtcsync
# Logging
logdir /var/log/chrony
log measurements statistics tracking
Complete Server Configuration
# /etc/chrony.conf
# Upstream NTS sources
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
# NTS server settings
ntsserverkey /etc/chrony/ssl/privkey.pem
ntsservercert /etc/chrony/ssl/fullchain.pem
ntsprocesses 1
ntsdumpdir /var/lib/chrony
# Serve time to clients
allow 10.0.0.0/8
allow 172.16.0.0/12
allow 192.168.0.0/16
# Serve as stratum 2 if upstream sources are lost
local stratum 2
# System clock
makestep 1.0 3
driftfile /var/lib/chrony/drift
rtcsync
# Rate limiting
ratelimit interval 1 burst 16
# Logging
logdir /var/log/chrony
log measurements statistics tracking
Certificate Management
Using Let's Encrypt with Certbot
certbot certonly --standalone -d ntp.example.com
Configure chrony to use the certificates:
ntsserverkey /etc/letsencrypt/live/ntp.example.com/privkey.pem
ntsservercert /etc/letsencrypt/live/ntp.example.com/fullchain.pem
Chrony automatically detects certificate file changes and reloads them without restart, which works well with certbot's automatic renewal.
File Permissions
Ensure chrony can read the private key:
chown root:chrony /etc/chrony/ssl/privkey.pem # Debian/Ubuntu: chown root:_chrony
chmod 640 /etc/chrony/ssl/privkey.pem
Firewall
Open the required ports:
# NTS-KE (TLS 1.3 key establishment)
firewall-cmd --permanent --add-port=4460/tcp
# NTP (time synchronization)
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload
Security Notes
NTS (Network Time Security, RFC 8915) uses TLS 1.3 exclusively for the NTS-KE (Key Establishment) phase. Chrony links against GnuTLS or OpenSSL for this; check your distribution's build. Because NTS mandates TLS 1.3, many older SSL/TLS attacks are simply not in scope:
- POODLE / BEAST / FREAK / LOGJAM / Sweet32: Not applicable. These attacks target SSL 3.0 and TLS 1.0/1.1 weaknesses; NTS-KE requires TLS 1.3 and rejects older protocol versions.
- Forward secrecy: Mandatory in TLS 1.3; every NTS-KE session uses an ephemeral key exchange.
- CRIME (CVE-2012-4929, 2012): TLS compression is not supported in TLS 1.3.
- Lucky13 / CBC padding oracles: Not applicable. TLS 1.3 uses AEAD-only ciphers and does not support CBC mode.
- Downgrade attacks: TLS 1.3 includes built-in downgrade protection via the ServerHello random value.
The following are not addressable through NTS/TLS configuration alone:
- Heartbleed (CVE-2014-0160, 2014): Only relevant if chrony is built against OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Not applicable if linked against GnuTLS. Addressed by keeping the TLS library patched.
- BREACH / CRIME (HTTP-layer): Not applicable. NTS is not an HTTP-based protocol.
- DROWN (CVE-2016-0800, 2016): Not applicable. NTS-KE only supports TLS 1.3; SSLv2 is not used.
Verification
Check NTS status for all sources:
chronyc -N authdata
You should see NTS in the Mode column and a non-zero cookie count:
Name/IP address Mode KeyID Type KLen Last Atmp NAK Cook CLen
================================================================
time.cloudflare> NTS 1 15 256 33m 0 0 8 100
nts.netnod.se NTS 1 15 256 33m 0 0 8 100
Check NTS-KE connection details:
chronyc ntpdata time.cloudflare.com
Verify the NTS-KE handshake uses TLS 1.3:
gnutls-cli --port 4460 time.cloudflare.com < /dev/null
Check overall time synchronization:
chronyc tracking
chronyc sources -v