How To Setup an NTS Server

Jun 2, 2023 · 10 mins read
How To Setup an NTS Server

In the video below, we show you how to setup an NTS server using Debian or Ubuntu


What we’ll be covering is how to set up a NTS server

Normally you would set up your own Network Time Protocol (NTP) server to get time from the Internet and point your internal computers to that

But NTP wasn’t designed with security in mind and so now we have Network Time Security (NTS) in its place

Install Chrony
Now because this video is about NTP and NTS, I’m going to assume that you already know how to install Ubuntu or Debian to save time

But to build our own time server we want to install chrony which is a popular solution for NTP, but it also supports NTS

Because I want to cover both Debian and Ubuntu, we’ll first switch to the root account

On Ubuntu you could use

sudo su -
Then supply your password

On Debian you could use

su -
Then supply the root password

We want to make sure that the package information is up to date before installing anything

apt update

Then we’ll install chrony

apt install chrony -y

Configure NTP Server:
We want to setup the computer to update its own clock using NTS

But by default, chrony will be configured to synch to some NTP servers

In which case, We’ll edit the config file

nano /etc/chrony/chrony.conf

Comment out any lines referencing NTP pools/servers by prepending the line with a #, for example

#pool 2.debian.pool.ntp.org iburst

And add the following line

server time.cloudflare.com iburst nts

At the time of recording, Cloudflare provide a Publicly available server which supports NTS

But it would be good to add others that you know of for redundancy, especially regional ones

The iburst option is intended to speed up the initial synchronisation which is benefical when a computer starts from cold for instance and it’s clock may have fallen behind a bit

The nts option is to request the use of NTS, otherwise it will just use NTP

Because most devices on your internal network will support NTP, and some may not support NTS, we’ll only configure this as an NTP server initially

It also makes sense to get NTP up and running first, before we add the NTS capabalities, to make sure this part is already working

By default, access to the NTP server will be blocked so we need to allow access but only for what’s necessary

And you can allow access by adding something like the following at the end of the config file

# Allow access to NTP server
allow 192.168.1.0/24

This line allows access to the NTP server for computers in the 192.168.1.0/24 network

Add additional lines for each internal network you want to access this

Now save the file and exit

Check if the NTP service is active

timedatectl status

If the output says that the NTP service is inactive, run the following command to activate it

timedatectl set-ntp true

Now restart the chrony service for the changes to take effect

systemctl restart chrony

Verify Chrony
We need to make sure the computer can synch its own time first

To view the time source servers being used by the computer, run the following command

chronyc sources -v

Assuming the computer’s clock is reasonably accurate, it should only take a brief amount of time for it to synchronise

When it does, you should see ^* at the start of the line. This is an easy way to see which server was chosen as the best, although in this example we’ve only told chrony about one server anyway

If all you see is ^? then the computer needs time to synchronise or cannot access that server

Running the following command will provide more details for the software clock and the synchronisation with the chosen server

chronyc tracking

While this command will provide further details on the time servers in terms of how close the clocks are to the computer’s for instance

chronyc sourcestats

And this command will let you confirm if you have an authenticated connection using NTS

chronyc -N authdata

In our case we’d expect to see the mode set to NTS for time.cloudflare.com

Once we know the server has been able to synch its clock with a time server, we can focus on internal clients

You can check NTP server statistics using the following command which can be useful to see NTP versus NTS use

chronyc -N serverstats

And the following command provides per client statistics, including details of if a specific device managed to connect using NTS

chronyc -N clients -k

NOTE: TLS, which is being used for NTS, relies on an accurate clock which puts us in a chicken and egg situation if your computer’s date and time is too far behind In which case check the date and time on the computer to make sure it’s up to date

date

If it’s not, we can fix this manually

We need to temporarily disable NTP to avoid an override

timedatectl set-ntp false

Then set the correct date and time, for instance

date -s '30 May 2023 13:05:00'

Now synch the hardware clock with the system clock we’ve just set

hwclock --systohc

And double check for good measure

hwclock

Now re-enable NTP

timedatectl set-ntp true

Configure UFW
It’s a good security practice to run a personal firewall such as UFW on Linux computers to further restrict access

In order to allow access to an internal NTP/NTS server add lines such as these

ufw allow proto udp from 192.168.1.0/24 to any port 123
ufw allow proto tcp from 192.168.1.0/24 to any port 4460

NOTE: If the server has more than one interface the rule should restrict the destination address as well to only the interface(s) NTP/NTS should be accessed on i.e. a non-management interface

Configure NTP Client
Internal clients will need to be reconfigured to use the NTP server as their source

For Linux clients, install chrony as before but use the server we’ve created as the source, for example

server 192.168.1.1 iburst

To view the time source servers being used by the computer, run the following command

sudo chronyc sources -v

NOTE: Because we have only setup NTP, you won’t see any authenticaion details if you check

Remove NTP Sources
On thing to point out is that a Linux distro may have its own NTP setup going on the background

On PoP!_OS for instance, I’ve noticed the computer tries to connect to several system76 servers using NTS

For security reasons this is being blocked by my firewall as the goal is for clients to connect to the internal server only and so only the NTP server has access to time servers on the Internet using TCP port 4460 and UDP port 123

If you see this and prefer for these other servers to not be used at all then remove any .sources file in the /etc/chrony/sources.d folder, for example

sudo rm /etc/chrony/sources.d/system76-nts.sources

Then restart chrony

sudo systemctl restart chrony

Configure NTS Server
If you have devices that support NTS and you can provide the server with a TLS certificate and private key that clients will trust, you can configure the NTP server to support NTS internally

How you do that depends on your circumstances, but you can set these up using OpenSSL for instance, just like you would for a web server

Bear in mind, you will then have to find a means to configure the client to trust the root CA

Once you have a certificate and private key, copy them to the /var/lib/chrony/ folder

And make sure these are readable by chrony, for example

chown _chrony:_chrony /var/lib/chrony/ntp1.key && chmod 0440 /var/lib/chrony/ntp1.key
chown _chrony:_chrony /var/lib/chrony/ntp1.crt && chmod 0440 /var/lib/chrony/ntp1.crt

Now edit the edit the config file

nano /etc/chrony/chrony.conf

And add the following lines for instance

ntsserverkey /var/lib/chrony/ntp1.key
ntsservercert /var/lib/chrony/ntp1.crt

While we’re here, check to make sure the following line is present higher up

ntsdumpdir /var/lib/chrony

If not, then add it

According to the chrony manual this is disabled by default, but I noticed the line was already there on a Debian server and is a recommendation from the likes of Red Hat who use chrony by default on their distros. This is THE Linux distro for enterprises so they must know something

This tells chrony where to save NTS cookies so that it doesn’t need to make an initial NTS-KE request when chronyd is started again

Restart the Chrony service for the changes to take effect

systemctl restart chrony

And check the service is working

systemctl status chrony

Bear in mind, NTS uses TCP port 4460 so if the server is behind a firewall, you will need to allow access to this. Access to UDP port 123 is still required as NTS-KE in the first phase and NTP in the second

Configure NTS Client
For NTS to work, the client needs to trust the Root CA that signed the TLS certificate

One option is to do this as part of the client setup of Chrony but rather than do this for one application/service I’d rather have the OS trust my Root CA so that this is a one off process

To do this on Debian based Linux distros, create a new folder for user provided certificates

sudo mkdir /usr/share/ca-certificates/extra

Copy the root CA certificate to this folder and make sure root owns this, for instance

sudo cp root-ca.crt /usr/share/ca-certificates/extra
sudo chown root:root /usr/share/ca-certificates/extra/root-ca.crt

Now edit the CA-certificates file

sudo nano /etc/ca-certificates.conf

Append the following line at the end

extra/root-ca.crt

For this to take effect update the CA certificates

sudo update-ca-certificates

You might get some feedback suggesting there was a problem, but if you run this command again it will no longer appear

You can then check if the connection works, by running this command for instance

chronyd -Q -t 3 'server ntp1.homelab.lan iburst nts maxsamples 1'

In this case we’re referencing the NTP server using its FQDN because that’s what the certificate was created for

Want you want to see is output like the following

2023-05-25T16:55:57Z chronyd version 4.2 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH +IPV6 -DEBUG)
2023-05-25T16:55:57Z Disabled control of system clock
2023-05-25T16:56:00Z System clock wrong by -0.000494 seconds (ignored)
2023-05-25T16:56:00Z chronyd exiting

In other words, this is telling us that the connection worked, albeit the clock is slightly different

To use NTS, update the chrony file

sudo nano /etc/chrony/chrony.conf

Change the existing line by using its FQDN instead and also add the nts parameter, for instance

server ntp1.homelab.lan iburst nts

Now restart the Chrony service for the changes to take effect

sudo systemctl restart chrony

To view the time source servers being used by the computer, run the following command

sudo chronyc sources -v

And this command will let you confirm if the connection is authenticated

sudo chronyc -N authdata

TIP: If the mode isn’t showing as NTS, but the server does show NTS had been used, reboot the client

Check Server Connections
As a final check, it’s worth looking to see what the server is reporting

You can check NTP server statistics using the following command which can be useful to see NTP versus NTS use

chronyc -N serverstats

And the following command provides per client statistics, including details of if a specific device managed to connect using NTS

chronyc -N clients -k

Sharing is caring!