🛠️ Server Setup Guide

Configuration Instructions for Stratum 1 NTP/NTS server

← Back to Main Page

Introduction

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:

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.


2. Prepare Serial Port

Start raspi-config:

sudo raspi-config
  1. Select option "Interface Options".
  2. Select option "Serial Port".
  3. At "Would you like a login shell to be accessible over serial?" Answer "No".
  4. At "Would you like the serial port hardware to be enabled?" Answer "Yes".
  5. Exit raspi-config and reboot the Pi.

3. Install Required Packages

sudo apt install gpsd pps-tools chrony apache2 python3-certbot-apache

4. Setup PPS

Edit /boot/firmware/cmdline.txt:

sudo nano /boot/firmware/cmdline.txt

At the end of the line, add the following:

bcm2708.pps_gpio_pin=18 nohz=off

5. Setup Serial

Create the script file:

sudo nano /usr/local/bin/configure-ttyAMA0.sh

Add the following content to the script:

#!/bin/bash /bin/stty -F /dev/ttyAMA0 raw 9600 cs8 clocal -cstopb -echo

Make the script executable:

sudo chmod +x /usr/local/bin/configure-ttyAMA0.sh

Create a systemd service to run this script:

sudo nano /etc/systemd/system/configure-serial-port.service

Add the following configuration:

[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

Enable and start the service:

sudo systemctl daemon-reload sudo systemctl enable configure-serial-port.service sudo systemctl start configure-serial-port.service

6. Set up Modules & Overlays

Edit modules configuration:

sudo nano /etc/modules-load.d/modules.conf

Add at the bottom:

pps-gpio

Edit /boot/firmware/config.txt:

sudo nano /boot/firmware/config.txt

Add the following at the bottom:

# PPS on PGIO pin 18 dtoverlay=pps-gpio,gpiopin=18

7. Setup gpsd

Edit gpsd defaults:

sudo nano /etc/default/gpsd

Change file to match the following:

DEVICES="/dev/ttyAMA0 /dev/pps0" GPSD_OPTIONS="-n" USBAUTO="false"

8. Setup Chrony

Edit daemon options:

sudo nano /etc/default/chrony

Change to:

DAEMON_OPTS="-F 1 -r"

Edit chrony configuration:

sudo nano /etc/chrony/chrony.conf

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

Enable services:

sudo systemctl enable gpsd sudo systemctl enable chrony

Reboot now:

sudo reboot

9. Setup Network Time Security (NTS)

Obtain an SSL Certificate (replace time.yourdomain.com with your domain):

sudo certbot --apache -d time.yourdomain.com

Copy certificates for chrony (replace time.yourdomain.com with your domain):

cd /etc/chrony sudo mkdir certs sudo su cat /etc/letsencrypt/live/time.yourdomain.com/fullchain.pem > /etc/chrony/certs/fullchain.pem cat /etc/letsencrypt/live/time.yourdomain.com/privkey.pem > /etc/chrony/certs/privkey.pem exit

Create a renewal hook script:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/chrony_NTS_certs.sh

Add script content:

#!/bin/bash FULLCHAIN_PATH="${RENEWED_LINEAGE}/fullchain.pem" PRIVKEY_PATH="${RENEWED_LINEAGE}/privkey.pem" cat "${FULLCHAIN_PATH}" > /etc/chrony/certs/fullchain.pem cat "${PRIVKEY_PATH}" > /etc/chrony/certs/privkey.pem systemctl restart chronyd systemctl restart gpsd

Make executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/chrony_NTS_certs.sh

Final reboot:

sudo reboot

Maintenance & Troubleshooting

Test NTS from another machine (replace time.yourdomain.com with your domain):

chronyd -Q -t 5 "server time.yourdomain.com iburst nts maxsamples 1"

Display serial settings:

stty -F /dev/ttyAMA0 -a
sudo setserial -v /dev/ttyAMA0

Display serial output:

cat /dev/ttyAMA0

Test PPS:

sudo ppstest /dev/pps0

Display GPS data:

cgps -s
gpsmon

Check service status:

sudo systemctl status chronyd
sudo systemctl status apache2
journalctl -xeu chrony.service

Let's Encrypt management:

sudo certbot renew –force-renewal
sudo certbot renew --dry-run