beaver

from Pogo, Walt Kelly

For putting out compiler fires.

2. Table of Contents

3. Introduction

NTS is a method for using TLS/SSL to authenticate NTP traffic on the net. That means that bad guys can’t forge packets that will give your system bogus time.

It is specified in RFC 8915, published in September 2020.

Note: The NTP Pool does not currently support NTS.

It is strongly suggested that you get a "normal", unauthenticated, NTP server working before enabling NTS. This may reduce the time spent debugging. See the Client Quick Start Guide.

While NTPsec already supported NTS as RFC 8915 still was in the draft phase, there unfortunately were incompatible changes introduced shortly before it was published. As a result, while NTPsec-versions before 1.1.9 do in principle support NTS, they cannot talk to any NTS servers or clients that implement the final RFC, which includes NTPsec-versions from 1.1.9 onwards. And NTPsec 1.1.9 requires manually specifying the correct port number (4460), because it still defaulted to 123. 1.2.0 is the first version of NTPsec to fully support NTS as specified in RFC 8915.

4. NTS Client Configuration

Append the keyword nts to the end of your server lines. Do this only for servers that speak NTS. If the server uses a port other than 4460 for NTS key exchange, you also need to specify the port number. As of August 2022, the following should work:

A list of public NTS servers is availabe, with more info on NTS. Look here first.

Listed below are development machines, so there may be gaps in availability, and they may run unreleased versions of NTPsec:

server ntpmon.dcs1.biz nts	# Singapore
server ntp1.glypnod.com nts	# San Francisco
server ntp2.glypnod.com nts	# London

Note that you must use the same host name that was used to create the server’s certificate. IP addresses will not work.

This assumes that the server is using a certificate covered by your OS/distro’s root certificate collection.

NetBSD needs the mozilla-rootcerts-openssl package and ca /etc/openssl/certs/ added to the server line.

Restart ntpd, and skip to Verification, below.

5. NTS Server Configuration

Being an NTS server requires a well-formed SSL certificate. The easiest way to do this is to use Let’s Encrypt. It needs a FQDN. Please see the certbot client site for instructions.

The following worked on Fedora:

$ sudo dnf install certbot

# Install
$ sudo certbot certonly --standalone

# Renew
$ sudo certbot renew
$ sudo killall -HUP ntpd

If you already have an SSL certificate for your server, and you are serving time using the same FQDN, you can reuse that certificate.

Next, add the line: nts enable to your ntp.conf file.

Locate the following two files:

  • Your certificate private key

  • Your certificate chain (i.e. your certificate followed by any intermediate CA certificates)

Then add the lines below to your ntp.conf, replacing with your pathnames.

Example, using Let’s Encrypt:

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

Note that ntpd must be able to read both files and you want to make sure that the bad guys can’t read your private key. It may be simpler to copy those files over to /etc/ntp/ and adjust their owner and mode so ntpd running as user ntp can read them.

You may need to tell your system where to store the keys used to encrypt cookies. The default is /var/lib/ntp/nts-keys. Some distros use /var/db/ rather than /var/lib/.

nts cookie /var/lib/ntp/nts-keys

Again, make sure the bad guys can’t read that file.

Restart your server, and skip to Verification, below.

6. Verification

Check your log file. The current client side NTS implementation is quite chatty. The log lines may change, but what you see should be similar to below.

As a client, you should see lines like this:

 3 Sep 13:36:40 ntpd[89030]: DNS: dns_probe: time.cloudflare.com, cast_flags:1, flags:21a01
 3 Sep 13:36:40 ntpd[89030]: NTSc: DNS lookup of time.cloudflare.com took 0.698 sec
 3 Sep 13:36:40 ntpd[89030]: NTSc: connecting to time.cloudflare.com:4460 => 162.159.200.1:4460
 3 Sep 13:36:41 ntpd[89030]: NTSc: set cert host: time.cloudflare.com
 3 Sep 13:36:44 ntpd[89030]: NTSc: Using TLSv1.3, TLS_AES_256_GCM_SHA384 (256)
 3 Sep 13:36:44 ntpd[89030]: NTSc: certificate subject name: /C=US/ST=California/L=San Francisco/O=Cloudflare, Inc./CN=time.cloudflare.com
 3 Sep 13:36:44 ntpd[89030]: NTSc: certificate issuer name: /C=US/O=DigiCert Inc/CN=DigiCert ECC Secure Server CA
 3 Sep 13:36:44 ntpd[89030]: NTSc: certificate is valid.
 3 Sep 13:36:44 ntpd[89030]: NTSc: Good ALPN from time.cloudflare.com
 3 Sep 13:36:46 ntpd[89030]: NTSc: read 750 bytes
 3 Sep 13:36:46 ntpd[89030]: NTSc: Using port 123
 3 Sep 13:36:46 ntpd[89030]: NTSc: Got 7 cookies, length 100, aead=15.
 3 Sep 13:36:46 ntpd[89030]: NTSc: NTS-KE req to time.cloudflare.com took 6.063 sec, OK
 3 Sep 13:36:46 ntpd[89030]: DNS: dns_check: processing time.cloudflare.com, 1, 21a01
 3 Sep 13:36:46 ntpd[89030]: DNS: Server taking: 162.159.200.1
 3 Sep 13:36:46 ntpd[89030]: DNS: Server poking hole in restrictions for: 162.159.200.1
 3 Sep 13:36:46 ntpd[89030]: PROTO: 162.159.200.1 unlink local addr 127.0.0.1 -> 192.168.1.2
 3 Sep 13:36:46 ntpd[89030]: DNS: dns_take_status: time.cloudflare.com=>good, 0
 3 Sep 13:36:47 ntpd[89030]: PROTO: 162.159.200.1 e014 84 reachable

For initializing a server, you should see lines like this:

11 Aug 12:24:12 ntpd[789]: INIT: OpenSSL 1.1.1g FIPS  21 Apr 2020, 1010107f
11 Aug 12:24:12 ntpd[789]: NTSs: starting NTS-KE server listening on port 4460
11 Aug 12:24:12 ntpd[789]: NTSs: OpenSSL security level is 1
11 Aug 12:24:12 ntpd[789]: NTSs: starting NTS-KE server listening on port 4460
11 Aug 12:24:12 ntpd[789]: NTSs: listen4 worked
11 Aug 12:24:12 ntpd[789]: NTSs: listen6 worked
11 Aug 12:24:12 ntpd[789]: NTSc: Using system default root certificates.
11 Aug 12:24:12 ntpd[789]: NTSs: loaded certificate (chain) from /etc/ntp/fullchain.pem
11 Aug 12:24:12 ntpd[789]: NTSs: loaded private key from /etc/ntp/privkey.pem
11 Aug 12:24:12 ntpd[789]: NTSs: Private Key OK

On a server, each time a client uses TLS to setup cookies, you should see lines like these. If all goes well, there is a single line for each connection.

11 Aug 12:29:38 ntpd[789]: NTSs: NTS-KE from 64.139.1.69:49253, Using TLSv1.3, TLS_AES_256_GCM_SHA384 (256), took 0.437 sec

Servers on the big bad internet will get a lot of garbage connections. The common cases produce a single line. Less common cases will have additional lines with OpenSSL error data.

26 Dec 18:13:55 ntpd[940892]: NTSs: SSL accept from 68.134.33.4:52188 failed: wrong version number, took 0.000 sec
26 Dec 18:24:20 ntpd[940892]: NTSs: SSL accept from 64.139.1.69:56525 failed, took 0.101 sec
26 Dec 18:24:20 ntpd[940892]: NTS: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca

alert means the client on the other end encountered troubles and is reporting them back to the server.

The logging prefix NTSs is for the NTS server component. The NTSc component is for the NTS client part, where your ntpd is talking to other NTS servers.

6.1. Check with ntpq

The output of ntpq will be slightly different when NTS is in use, note the t column. Example:

root@ntpmon:/var/www/html/ntp# ntpq -p
     remote                                   refid      st t when poll reach   delay   offset   jitter
*SHM(1)                                  .PPS.            0 l   20   64  377   0.0000   0.0007   0.0281
xSHM(0)                                  .GPS.            0 l   19   64  377   0.0000 233.3966  19.2212
+pi3.rellim.com                          .PPS.            1 8   56   64  371 197.4484   0.0932   0.9660
+kong.rellim.com                         204.17.205.17    2 8   17   64  273 210.7230  -1.3924   0.6086
-ntp1.glypnod.com                        204.123.2.72     2 8   50   64  277 178.5749   3.8921   0.9611
-ntp2.glypnod.com                        17.253.34.253    2 8    -   64  177 185.7582  -2.6534   0.0275
 2407:8000:8001:80::8                    .DNS.           16 u    - 1024    0   0.0000   0.0000   0.0005
-navobs1.wustl.edu                       .GPS.            1 u  105   64  356 221.5282  -2.4354   0.0293

The t column shows how many cookies your NTS client is holding for the appropriate servers. The number should be 8. Lower numbers indicate dropped packets. (7 could be a packet in flight.)

The RFC calls for the server to rotate the private key used to encrypt cookies every 24 hours. The server also saves the previous key so old cookies will work for at least 24 hours. 24 hours and 8 cookies will work for a polling interval of up to 3 hours. That’s much longer than the default maxpoll of 10 (1024 seconds).

6.2. Check ntp variables

Try ntpq -c nts. This will show various counters related to NTS. This feature is under active development, so the format might change. An example:

root@ntpmon:/var/www/html/ntp# ntpq -c nts
NTS client sends:            7491
NTS client recvs:            6562
NTS client recvs w error:    0
NTS server recvs:            5591
NTS server recvs w error:    38
NTS server sends:            5553
NTS make cookies:            6392
NTS decode cookies:          4734
NTS decode cookies old:      819
NTS decode cookies too old:  0
NTS decode cookies error:    0
NTS KE probes:               8
NTS KE probes_bad:           0
NTS KE serves:               75
NTS KE serves_bad:           56

7. References