Banner image of NTS – Securing NTP with RFC 8915

NTS – Securing NTP with RFC 8915

The Network Time Protocol (NTP) is one of the remaining protocols on the internet without modern security. The new 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 securely synchronize the time.

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

Introduction

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 nearly 40 years old, the current version 4 (NTPv4) was published in 2010. Like many other network protocols invented in the last century, NTP doesn’t come with modern security.

NTPv4 (RFC 5905) defines three protocol modes (symmetric, client-server, and broadcast). On your PC, you usually use the “client-server” variant. In this mode, your operating system is the NTP client that synchronizes its time with upstream NTP servers, which are preconfigured on your system. Like DNS servers, NTP uses a hierarchy of servers to synchronize the time (depending on the “Stratum” number). NTP uses UDP port 123 for servers and clients.

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) uses TLS 1.3, AEAD, and digital certificates. Apart from the apparent objectives of providing confidentiality, authenticity, and integrity, NTS also aims to protect against replay attacks, some kinds of tracking, and more (see section 1.1 of RFC 8915).

As mentioned above, NTS requires TLS 1.3 and ALPN. For the TLS handshake (the NTS Key Establishment (NTS-KE)), NTS uses TCP port 4460. For the remaining traffic, the server and client negotiate a UDP port (or use NTP’s default UDP port 123).

On the client, NTS saves the state in encrypted NTS cookies. 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 that tries to secure NTP and isn’t directly related to the release of NTS. At this writing, the latest version of NTPSec is 1.1.9.

NTPSec already supports NTS and is available for many Linux distributions (e.g., Arch Linux, Ubuntu). For this tutorial, we choose NTPSec. You can also try other NTP implementations that support NTS.

Configuring NTPSec for NTS

We talked about NTP, NTS, and NTPSec. Now, it is time to put it all together.

The final missing component is an NTP server that supports NTS. In this tutorial, we use Cloudflare’s NTS service. Cloudflare isn’t required, but only one example. You can also use any other NTP server that supports NTS.

Step 1: Installing NTPSec

First of all, you need to install NTPSec (or another NTP implementation that supports NTS). The current NTPSec 1.1.9 (released in May 2020) is available for Arch (via AUR: yay -S ntpsec) or in the Universe repository of Ubuntu Groovy. Check the availability for your repository if needed.

On Ubuntu Groovy (aka Ubuntu 20.10), you might need to add the Universe repository to the sources of APT: sudo add-apt-repository universe. After adding the repository, you can install NTPSec: sudo apt install ntpsec. You should see output similar to:

The following packages will be REMOVED: systemd-timesyncd The following NEW packages will be installed: ntpsec python3-ntp Do you want to continue? [Y/n]

Press Y to continue.

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 Sat 2020-10-03 08:08:45 CEST

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

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

Step 3: Migrating from NTP to NTS

The final step is unspectacular. The “ntp.conf” file of NTPSec already contains a line for NTS. You need to comment out “normal” NTP and enable NTS. Furthermore, NTS-KE uses the TCP port 4460. So, we need to change the port, too.

Open the “ntp.conf” file: sudo nano /etc/ntpsec/ntp.conf. Comment out the lines that start with “pool” and “server.” It 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

Then, enable the NTS line in the file by removing the “#” in front of the line. As mentioned before, replace the TCP port number with 4460, as required by NTS-KE. It should look like:

# Public NTP servers supporting Network Time Security: server time.cloudflare.com:4460 nts

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[11609]: INIT: OpenSSL 1.1.1f 31 Mar 2020, 1010106f … ntpd[11609]: NTSc: Using system default root certificates. … ntpd[11609]: DNS: dns_probe: time.cloudflare.com:4460, cast_flags:1, flags:21801 … ntpd[11609]: NTSc: DNS lookup of time.cloudflare.com:4460 took 0.197 sec … ntpd[11609]: NTSc: connecting to time.cloudflare.com:4460 => 162.159.200.1:4460 … ntpd[11609]: NTSc: set cert host: time.cloudflare.com … ntpd[11609]: NTSc: Using TLSv1.3, TLS_AES_256_GCM_SHA384 (256) … ntpd[11609]: NTSc: certificate subject name: /C=US/ST=California/L=San Francisco/O=Cloudflare, Inc./CN=time.cloudflare.com … ntpd[11609]: NTSc: certificate issuer name: /C=US/O=DigiCert Inc/CN=DigiCert ECC Secure Server CA … ntpd[11609]: NTSc: certificate is valid. … ntpd[11609]: NTSc: Good ALPN from time.cloudflare.com:4460 … ntpd[11609]: NTSc: read 750 bytes … ntpd[11609]: NTSc: Using port 123 … ntpd[11609]: NTSc: Got 7 cookies, length 100, aead=15. … ntpd[11609]: NTSc: NTS-KE req to time.cloudflare.com:4460 took 0.279 sec, OK … ntpd[11609]: DNS: dns_check: processing time.cloudflare.com:4460, 1, 21801 … ntpd[11609]: DNS: Server taking: 162.159.200.1 … ntpd[11609]: DNS: Server poking hole in restrictions for: 162.159.200.1 … ntpd[11609]: DNS: dns_take_status: time.cloudflare.com:4460=>good, 0

Finally, check the peers of NTP on your device: ntpq -p.

The output should contain a “t” column, which should show “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.

Follow us on Mastodon:
@infosechandbook

Summary

NTS adds modern cryptography to NTP and helps to get rid of insecure network protocols. NTPSec is an NTP implementation for Linux that allows you to use NTS now.

Keep in mind that RFC 8915 is fresh from the press, so there may be some changes in NTS client and server implementations.