NTS – Securing NTP with RFC 8915

The Network Time Protocol (NTP) is one of the remaining protocols on the internet without state-of-the-art security. The RFC 8915 “Network Time Security for the Network Time Protocol” tries to change this by proposing cryptographic protection for NTP’s client-server mode. In this article, we use the NTP implementation “NTPsec” and NTS to synchronize the system’s time securely.

Always stay in the loop!
Subscribe to our RSS/Atom feed.


In this section, we briefly introduce NTP, NTS, and NTPSec. If you don’t need the theory, jump to Configuring NTPSec for NTS.

The Network Time Protocol (NTP)

David L. Mills invented NTP in 1981. While the original NTP is more than 40 years old, the current version 4 (NTPv4) was published in 2010. NTP doesn’t come with modern security like many other network protocols invented in the last century.

NTPv4 (RFC 5905) defines three protocol modes (symmetric, client-server, and broadcast). Your operating system likely uses the “client-server” mode. In this mode, your operating system is the NTP client, synchronizing your system’s time with NTP servers. The list of NTP servers is often preconfigured on your system. NTP uses a hierarchy of servers to synchronize the time (technically, it depends on the “Stratum” number).

While NTP traditionally uses UDP port 123 for servers and clients, the new RFC 9109 allows randomizing ports in certain cases.

RFC 8915 “Network Time Security for the Network Time Protocol”

RFC 8915, released in September 2020, describes the “Network Time Security for the Network Time Protocol.” It only covers the “client-server” variant of NTPv4.

Network Time Security (NTS) relies on TLS 1.3, AEAD, and digital certificates. Apart from the apparent objectives of providing confidentiality, authenticity, and integrity, NTS aims to protect against replay attacks, some kinds of tracking, and more (see section 1.1 of RFC 8915).

NTS uses the dedicated TCP port 4460 for the TLS handshake, called NTS Key Establishment (NTS-KE). For the remaining traffic, the server and client negotiate a UDP port or use NTP’s default UDP port 123.

NTS saves the state in encrypted NTS cookies on the client (your operating system). The client sends these NTS cookies to the NTS server once. If there are no cookies on the client, it should rerun NTS-KE to get a fresh set. The contents of cookies depend on the NTS server implementation and aren’t part of RFC 8915.

The NTPSec project

The NTPSec project released its version 1.0.0 of a “secure, hardened, and improved implementation of Network Time Protocol” in 2017. It is an open-source implementation for Linux, trying to secure NTP. NTPSec isn’t directly related to the release of NTS.

NTPSec supports NTS and is available for many Linux distributions (e.g., Arch Linux, Ubuntu). If your operating system isn’t supported, try other NTP implementations that support NTS.

Configuring NTPSec for NTS

We talked about NTP, NTS, and NTPSec. Let’s put it all together.

The following steps require knowledge of operating system commands and network protocols. If you don't know most or any of these commands, do not proceed. Configuring your operating system by blindly following tutorials on the internet might result in less security and privacy.

The final missing component is an NTP server supporting NTS. We use “nts.ntp.se” in this tutorial. You can use any other NTP server supporting NTS.

Step 1: Installing NTPSec

You need to install NTPSec or another NTP implementation supporting NTS. The latest version of NTPSec is 1.2.1, released in June 2021.

  • Arch users can install the latest version via AUR: yay -S ntpsec.
  • Ubuntu users can install an older version via the Universe repository: sudo apt install ntpsec. You may need to add the Universe repository to APT’s sources first: sudo add-apt-repository universe.
  • Read the documentation of the tool if you run other operating systems.

NTPSec might install “python3-ntp” and other packages as dependencies.

Step 2: Check whether “normal” NTP synchronization works

Check whether NTPSec runs on your device: systemctl status ntpsec. You should see output like:

Active: active (running) since Mon 2021-09-06 04:37:49 UTC

After this, check your syslog file: grep "ntpd" /var/log/syslog. The log file should contain lines similar to:

… ntpd[6572]: DNS: dns_probe: ntp.ubuntu.com, cast_flags:1, flags:20801 … ntpd[6572]: DNS: dns_check: processing ntp.ubuntu.com, 1, 20801 … ntpd[6572]: DNS: Server taking: … ntpd[6572]: DNS: Server poking hole in restrictions for: … ntpd[6572]: DNS: dns_take_status: ntp.ubuntu.com=>good, 0

If your output looks similar, “normal” NTP works. We can proceed setting up NTS.

Step 3: Migrating from NTP to NTS

The “ntp.conf” file of NTPSec contains a line for NTS. You need to disable NTP and enable NTS.

NTS-KE (the key exchange of NTS) uses TCP port 4460. You may need to point to this TCP port in your configuration, depending on the NTS server you choose.

Open the “ntp.conf” file: sudo nano /etc/ntpsec/ntp.conf. Comment out the lines starting with “pool” and “server” to disable NTP. The changed lines should look like:

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board # on 2011-02-08 (LP: #104525). See https://www.pool.ntp.org/join.html for # more information. #pool 0.ubuntu.pool.ntp.org iburst #pool 1.ubuntu.pool.ntp.org iburst #pool 2.ubuntu.pool.ntp.org iburst #pool 3.ubuntu.pool.ntp.org iburst # Use Ubuntu's ntp server as a fallback. #server ntp.ubuntu.com

Enable NTS by removing the “#” in front of the example in the file. The changed line may look like:

# Public NTP servers supporting Network Time Security: server nts.ntp.se:4443 nts

In this example, the NTS server “nts.ntp.se” uses TCP port 4443, and doesn’t support the dedicated TCP port 4460 for NTS-KE.

Restart NTPSec: sudo systemctl restart ntpsec.

Step 4: Check whether synchronization via NTS works

Check your syslog file again: grep "ntpd" /var/log/syslog. The log file should contain lines similar to:

… ntpd[12124]: INIT: OpenSSL 1.1.1f 31 Mar 2020, 1010106f … ntpd[12124]: NTSc: Using system default root certificates. … ntpd[12124]: DNS: dns_probe: nts.ntp.se:4443, cast_flags:1, flags:21801 … ntpd[12124]: NTSc: DNS lookup of nts.ntp.se:4443 took 0.063 sec … ntpd[12124]: NTSc: connecting to nts.ntp.se:4443 => … ntpd[12124]: NTSc: set cert host: nts.ntp.se … ntpd[12124]: NTSc: Using TLSv1.3, TLS_AES_256_GCM_SHA384 (256) … ntpd[12124]: NTSc: certificate subject name: /CN=nts.ntp.se … ntpd[12124]: NTSc: certificate issuer name: /C=US/O=Let's Encrypt/CN=R3 … ntpd[12124]: NTSc: certificate is valid. … ntpd[12124]: NTSc: Good ALPN from nts.ntp.se:4443 … ntpd[12124]: NTSc: read 878 bytes … ntpd[12124]: NTSc: Using server sth-ts.nts.netnod.se=> … ntpd[12124]: NTSc: Using port 4123 … ntpd[12124]: NTSc: Got 8 cookies, length 100, aead=15. … ntpd[12124]: NTSc: NTS-KE req to nts.ntp.se:4443 took 0.298 sec, OK … ntpd[12124]: DNS: dns_check: processing nts.ntp.se:4443, 1, 21801 … ntpd[12124]: DNS: Server taking: … ntpd[12124]: DNS: Server poking hole in restrictions for: … ntpd[12124]: DNS: dns_take_status: nts.ntp.se:4443=>good, 0

Check the peers of NTP on your device: ntpq -p. The output should contain a “t” column, showing “8.” In this case, “8” is the number of NTS cookies held by NTPSec. If you see lower numbers (esp. “6” or below), there could be some connectivity issues on your side. You may need to change the TCP port or NTS server in this case.

Enter ntpq -c nts. If everything runs as expected, the lines “NTS client sends” and “NTS client recvs good” show the same value.


NTS adds state-of-the-art cryptography to NTP and helps to get rid of insecure network protocols. NTPSec is an NTP implementation for Linux allowing you to use NTS.

Regularly review your configuration and look for issues as NTS is fairly new.

We republished this article in September 2021.