Skip to content

Last updated: 2026-02-11

NTPsec NTS Configuration Guide

This guide provides recommended Network Time Security (NTS) settings for NTPsec. NTPsec is a security-focused fork of the reference NTP implementation with hardened code, reduced attack surface, and NTS support since version 1.2.0. NTS authenticates time synchronization using TLS, preventing man-in-the-middle attacks on time data.

Prerequisites

Availability: NTPsec is available in Debian 11+ and Ubuntu 22.04+ repositories. It is not in the base RHEL/CentOS or SLES repositories — on those systems, install from EPEL or build from source. Note that RHEL uses chrony as its default NTP implementation.

Path note: This guide uses Debian/Ubuntu package paths. On source builds (common on RHEL/SLES), paths differ: config is typically /etc/ntp.conf (not /etc/ntpsec/ntp.conf), state files are under /var/lib/ntp/ (not /var/lib/ntpsec/), logs are under /var/log/ntp/ (not /var/log/ntpsec/), and the service is ntpd (not ntpsec). The user/group is ntp on source builds vs ntpsec on Debian/Ubuntu packages.

NTS Overview

NTS works in two phases:

  1. NTS-KE (Key Establishment) -- A TLS 1.3 handshake on port 4460 authenticates the server and establishes shared keys
  2. 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/ntpsec/ntp.conf

server time.cloudflare.com nts
server nts.netnod.se nts
server ptbtime1.ptb.de nts
server ntppool1.time.nl nts

Certificate Trust Store

NTPsec uses the system trust store by default. To specify a custom CA bundle:

# Debian/Ubuntu:
nts ca /etc/ssl/certs/ca-certificates.crt
# RHEL/CentOS (source builds): /etc/pki/tls/certs/ca-bundle.crt
# SLES: /etc/ssl/ca-bundle.pem

NTS Cookie Storage

Persist NTS cookies across restarts to avoid repeated NTS-KE handshakes:

nts cookie /var/lib/ntpsec/nts-cookies    # source builds: /var/lib/ntp/nts-cookies

AEAD Algorithm

NTPsec supports AEAD algorithm selection for NTS cookie encryption. The default (AES-SIV-CMAC-256) is recommended:

nts aead AES_SIV_CMAC_256

Server Configuration

NTS-KE Server

Configure NTPsec as an NTS-capable NTP server:

# /etc/ntpsec/ntp.conf

nts cert /etc/ntpsec/ssl/fullchain.pem
nts key /etc/ntpsec/ssl/privkey.pem

The certificate must be valid for the server's hostname.

TLS Protocol Versions

Restrict TLS versions for the NTS-KE handshake:

nts mintls TLS1.3
nts maxtls TLS1.3

To allow TLS 1.2 as well:

nts mintls TLS1.2

NTS-KE Port

By default, NTPsec listens on port 4460 for NTS-KE. To change it:

nts port 4461

Complete Client Configuration

# /etc/ntpsec/ntp.conf

# NTS-authenticated time sources
server time.cloudflare.com nts
server nts.netnod.se nts
server ptbtime1.ptb.de nts
server ntppool1.time.nl nts

# Fallback (unauthenticated) sources
pool pool.ntp.org iburst

# NTS cookie persistence
nts cookie /var/lib/ntpsec/nts-cookies   # source builds: /var/lib/ntp/nts-cookies

# Drift file
driftfile /var/lib/ntpsec/ntp.drift      # source builds: /var/lib/ntp/ntp.drift

# Logging
logfile /var/log/ntpsec/ntpd.log         # source builds: /var/log/ntp/ntpd.log
statsdir /var/log/ntpsec/                # source builds: /var/log/ntp/
statistics loopstats peerstats

Complete Server Configuration

# /etc/ntpsec/ntp.conf

# Upstream NTS sources
server time.cloudflare.com nts
server nts.netnod.se nts

# NTS server settings
nts cert /etc/ntpsec/ssl/fullchain.pem
nts key /etc/ntpsec/ssl/privkey.pem
nts mintls TLS1.2
nts cookie /var/lib/ntpsec/nts-cookies    # source builds: /var/lib/ntp/nts-cookies

# Serve time to clients
restrict default kod nomodify nopeer noquery limited
restrict 127.0.0.0 mask 255.0.0.0
restrict ::1
restrict 10.0.0.0 mask 255.0.0.0 nomodify notrap
restrict 172.16.0.0 mask 255.240.0.0 nomodify notrap
restrict 192.168.0.0 mask 255.255.0.0 nomodify notrap

# Drift file
driftfile /var/lib/ntpsec/ntp.drift      # source builds: /var/lib/ntp/ntp.drift

# Logging
logfile /var/log/ntpsec/ntpd.log         # source builds: /var/log/ntp/ntpd.log
statsdir /var/log/ntpsec/                # source builds: /var/log/ntp/
statistics loopstats peerstats

Certificate Management

Using Let's Encrypt with Certbot

certbot certonly --standalone -d ntp.example.com

Configure NTPsec to use the certificates:

nts cert /etc/letsencrypt/live/ntp.example.com/fullchain.pem
nts key /etc/letsencrypt/live/ntp.example.com/privkey.pem

Restart NTPsec after certificate renewal since it does not automatically reload certificates:

certbot renew --deploy-hook "systemctl restart ntpsec"  # source builds: systemctl restart ntpd

File Permissions

Ensure NTPsec can read the private key:

chown root:ntpsec /etc/ntpsec/ssl/privkey.pem  # source builds: chown root:ntp
chmod 640 /etc/ntpsec/ssl/privkey.pem

Firewall

Open the required ports.

RHEL/CentOS (firewalld):

firewall-cmd --permanent --add-port=4460/tcp
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload

Debian/Ubuntu (ufw):

ufw allow 4460/tcp
ufw allow 123/udp

Verification

Check NTS status for all peers:

ntpq -c nts

Check peer status and authentication:

ntpq -p

Verify the NTS-KE handshake:

gnutls-cli --port 4460 time.cloudflare.com < /dev/null

Check overall time synchronization:

ntpq -c sysinfo
ntpq -c iostats

Check NTPsec version and build options:

ntpd --version