The following instructions can be used to set up a public NTP/NTS server running chrony on a Raspberry Pi, with automatic SSL certificate renewals from Let’s Encrypt Certificate Authority.
Please note the following important points:
These instructions were developed for a Raspberry Pi 5 running Raspberry Pi OS Trixie.
These instructions can easily be adapted to a Raspberry Pi 4. The only difference is the serial device on a Pi 5 is /dev/ttyAMA0 while on a Pi 4 it is /dev/ttyS0. Therefore if you are setting this up on a Pi 4, replace all instances of ttyAMA0 with ttyS0. Everything else remains the same.
In our setup, we use a Waveshare NEO-M8T timing HAT (Part No.: NEO-M8T GNSS TIMING HAT), which can be purchased on the Waveshare website. This circuit board conveniently attaches to the GPIO pins and receives power from the Pi.
We configured the NEO-M8T module as follows:
Accept Galileo satellite navigation system signal only, but you may chose whichever GNSS that you prefer, within the limitations of the module.
Surveyed-in the module so that it enters the timing mode for maximum timing accuracy.
Set the baud rate at 9600. The serial configurations below take this into consideration so if your device’s baud rate is different, then you will need to adjust accordingly.
Set NMEA to version 4.10.
Note: Configuring the NEO-M8T module is complex and is outside the scope of this tutorial. We suggest that you consult the user manual for this module.
It is expected that you have SSH access or terminal access and are proficient enough to execute commands and edit text files (e.g., using nano).
Power Warning: Care must be taken not to power the circuit board via the USB port while it is also receiving power from the Pi. You can connect only one source of power at a time! To ensure the board does not receive power from the USB port (e.g., when connecting to a computer for u-center software), we use a Portapow USB Power Blocker. This blocks power from the computer while allowing data signals through.
1. Configure the Firewall
Configure your firewall to allow ports 80, 123, and 4460 and forward them to the Raspberry Pi.
Port 80 (TCP): Required for automated SSL certificate renewal.
Port 123 (UDP): Required for NTP.
Port 4460 (TCP): Required for NTS key exchange.
2. Prepare Serial Port
Start raspi-config:
sudo raspi-config
Select option "Interface Options".
Select option "Serial Port".
At "Would you like a login shell to be accessible over serial?" Answer "No".
At "Would you like the serial port hardware to be enabled?" Answer "Yes".
[Unit]
Description=Configure Serial Port ttyAMA0 Settings
# This ensures the service runs only after the device node is present
After=dev-ttyAMA0.device
[Service]
Type=oneshot
ExecStart=/usr/local/bin/configure-ttyAMA0.sh
[Install]
WantedBy=multi-user.target
Apply the following changes (comment out default pools and default DHCP sources):
#pool 2.debian.pool.ntp.org iburst
#sourcedir /run/chrony-dhcp
dumpdir /var/run/chrony
makestep 1 1
# Set maximum client log size
clientloglimit 2147483648
# Set rate limits
ratelimit
ntsratelimit
# Allow all
allow
# Certificate in the PEM format
ntsservercert /etc/chrony/certs/fullchain.pem
# Private key in the PEM format
ntsserverkey /etc/chrony/certs/privkey.pem
# Number of helper processes for NTS
ntsprocesses 10
# Maximum number of concurrent NTS-KE connections per process
maxntsconnections 512
# Main reference clock using socket interface
refclock SOCK /run/chrony.pps0.sock refid GNSS precision 1e-9