Implement Network Time Security (NTS) for encrypted time synchronization with chrony

Intermediate 25 min Jun 07, 2026 396 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Network Time Security (NTS) with chrony to provide cryptographically authenticated and encrypted time synchronization, protecting against time-based attacks and ensuring secure clock synchronization across your infrastructure.

Prerequisites

  • Root or sudo access
  • Network connectivity on ports 123/udp and 4460/tcp
  • Basic understanding of time synchronization concepts

What this solves

Network Time Security (NTS) provides cryptographically authenticated and encrypted time synchronization, protecting your servers from time-based attacks and manipulation. Traditional NTP lacks authentication, making it vulnerable to spoofing attacks that can disrupt security protocols, certificate validation, and distributed systems that rely on synchronized clocks.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you have the latest versions available.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install chrony with NTS support

Install chrony which includes NTS support in modern versions. We also install gnutls-utils for certificate management.

sudo apt install -y chrony gnutls-bin
sudo dnf install -y chrony gnutls-utils

Stop chrony service

Stop the chrony service before making configuration changes to prevent conflicts.

sudo systemctl stop chrony

Create NTS keys directory

Create a directory for NTS keys and certificates with proper permissions for the chrony user.

sudo mkdir -p /var/lib/chrony/nts
sudo chown chrony:chrony /var/lib/chrony/nts
sudo chmod 750 /var/lib/chrony/nts

Configure chrony NTS client

Configure chrony to use NTS-enabled time servers. This configuration uses CloudFlare's NTS servers as the primary source.

# NTS-enabled time servers
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts
server nts.time.nl iburst nts

# Fallback to standard NTP if NTS fails
pool 2.pool.ntp.org iburst

# Record the rate at which the system clock gains/loses time
driftfile /var/lib/chrony/drift

# Allow the system clock to be stepped in the first three updates
makestep 1.0 3

# Enable kernel synchronization of the real-time clock (RTC)
rtcsync

# NTS key and certificate storage
ntsservercert /var/lib/chrony/nts/server.crt
ntsserverkey /var/lib/chrony/nts/server.key
ntsdumpdir /var/lib/chrony/nts

# Enhanced logging
log tracking measurements statistics
logdir /var/log/chrony

# Security settings
user chrony
lock_all

# Allow only specific subnets to query time (if acting as server)
allow 192.168.0.0/16
allow 10.0.0.0/8
allow 172.16.0.0/12

Generate NTS server certificates

If you want to provide NTS service to other systems, generate certificates for the NTS server component.

sudo openssl req -x509 -newkey rsa:4096 -keyout /var/lib/chrony/nts/server.key -out /var/lib/chrony/nts/server.crt -days 365 -nodes -subj "/C=US/ST=State/L=City/O=Organization/CN=$(hostname -f)"
sudo chown chrony:chrony /var/lib/chrony/nts/server.key /var/lib/chrony/nts/server.crt
sudo chmod 600 /var/lib/chrony/nts/server.key
sudo chmod 644 /var/lib/chrony/nts/server.crt

Configure NTS server settings

Add NTS server configuration to allow other systems to sync with authenticated time. This enables port 4460 for NTS-KE (Key Exchange).

# Add these lines to existing configuration for NTS server functionality
ntsport 4460
ntstrustedcerts /var/lib/chrony/nts
ntsprocesses 4
ntsrotate 86400

Configure firewall for NTS

Open the necessary ports for NTS operation. Port 123 is for NTP, and port 4460 is for NTS-KE.

sudo ufw allow 123/udp comment 'NTP'
sudo ufw allow 4460/tcp comment 'NTS-KE'
sudo ufw reload
sudo firewall-cmd --permanent --add-port=123/udp
sudo firewall-cmd --permanent --add-port=4460/tcp
sudo firewall-cmd --reload

Create chrony log directory

Ensure the log directory exists and has correct permissions for chrony to write log files.

sudo mkdir -p /var/log/chrony
sudo chown chrony:chrony /var/log/chrony
sudo chmod 755 /var/log/chrony

Start and enable chrony

Start the chrony service and enable it to start automatically on boot.

sudo systemctl enable --now chrony
sudo systemctl status chrony

Configure NTS client authentication

Verify NTS authentication

Check that NTS authentication is working by examining the chrony sources and their authentication status.

sudo chronyc sources -v
sudo chronyc authdata

Configure NTS certificate validation

Set up certificate validation parameters for enhanced security. This ensures certificates are properly verified.

# Add certificate validation settings
nocerttimecheck 1
ntscachedir /var/lib/chrony/nts
ntstimeout 10

Restart chrony with new configuration

Restart chrony to apply the certificate validation settings.

sudo systemctl restart chrony

Set up NTS server with certificate management

Configure automatic certificate renewal

Create a script to automatically renew NTS certificates before they expire.

#!/bin/bash

# NTS Certificate Renewal Script
CERT_DIR="/var/lib/chrony/nts"
CERT_FILE="$CERT_DIR/server.crt"
KEY_FILE="$CERT_DIR/server.key"
HOSTNAME=$(hostname -f)

# Check if certificate expires within 30 days
if openssl x509 -checkend 2592000 -noout -in "$CERT_FILE" >/dev/null 2>&1; then
    echo "Certificate is still valid for more than 30 days"
    exit 0
fi

echo "Certificate expires within 30 days, renewing..."

# Generate new certificate
openssl req -x509 -newkey rsa:4096 -keyout "$KEY_FILE.new" -out "$CERT_FILE.new" -days 365 -nodes -subj "/C=US/ST=State/L=City/O=Organization/CN=$HOSTNAME"

# Set proper permissions
chown chrony:chrony "$KEY_FILE.new" "$CERT_FILE.new"
chmod 600 "$KEY_FILE.new"
chmod 644 "$CERT_FILE.new"

# Replace old certificates
mv "$KEY_FILE.new" "$KEY_FILE"
mv "$CERT_FILE.new" "$CERT_FILE"

# Restart chrony to use new certificate
systemctl restart chrony

echo "Certificate renewed successfully"

Make renewal script executable

Set proper permissions on the certificate renewal script and test it.

sudo chmod +x /usr/local/bin/renew-nts-cert.sh
sudo /usr/local/bin/renew-nts-cert.sh

Schedule automatic certificate renewal

Create a cron job to run the certificate renewal script weekly.

sudo crontab -e

Add this line to run the renewal check every Sunday at 2 AM:

0 2 * * 0 /usr/local/bin/renew-nts-cert.sh >> /var/log/chrony/cert-renewal.log 2>&1

Monitor and troubleshoot NTS connections

Create NTS monitoring script

Create a monitoring script to check NTS authentication status and log any issues.

#!/bin/bash

# NTS Monitoring Script
LOGFILE="/var/log/chrony/nts-monitor.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

echo "[$TIMESTAMP] Starting NTS monitoring check" >> "$LOGFILE"

# Check chrony status
if ! systemctl is-active --quiet chrony; then
    echo "[$TIMESTAMP] ERROR: chrony service is not running" >> "$LOGFILE"
    exit 1
fi

# Check NTS authentication
NTS_SOURCES=$(chronyc sources -v | grep -c 'nts')
if [ "$NTS_SOURCES" -eq 0 ]; then
    echo "[$TIMESTAMP] WARNING: No NTS sources found" >> "$LOGFILE"
else
    echo "[$TIMESTAMP] INFO: Found $NTS_SOURCES NTS sources" >> "$LOGFILE"
fi

# Check authentication data
AUTH_DATA=$(chronyc authdata 2>/dev/null)
if [ $? -eq 0 ]; then
    echo "[$TIMESTAMP] INFO: NTS authentication data available" >> "$LOGFILE"
else
    echo "[$TIMESTAMP] WARNING: Could not retrieve NTS authentication data" >> "$LOGFILE"
fi

# Check time synchronization
TRACKING=$(chronyc tracking)
STRATUM=$(echo "$TRACKING" | grep 'Stratum' | awk '{print $3}')
if [ "$STRATUM" -le 4 ]; then
    echo "[$TIMESTAMP] INFO: Time synchronized (stratum $STRATUM)" >> "$LOGFILE"
else
    echo "[$TIMESTAMP] WARNING: Poor time synchronization (stratum $STRATUM)" >> "$LOGFILE"
fi

echo "[$TIMESTAMP] NTS monitoring check completed" >> "$LOGFILE"

Set up NTS monitoring cron job

Make the monitoring script executable and schedule it to run every 15 minutes.

sudo chmod +x /usr/local/bin/nts-monitor.sh
sudo crontab -e

Add this line for monitoring every 15 minutes:

*/15 * * * * /usr/local/bin/nts-monitor.sh

Configure log rotation for NTS logs

Set up log rotation to prevent NTS log files from growing too large.

/var/log/chrony/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 chrony chrony
    postrotate
        systemctl reload chrony > /dev/null 2>&1 || true
    endrotate
}

Verify your setup

Confirm that NTS is working correctly and time synchronization is secure.

sudo chronyc sources -v
sudo chronyc tracking
sudo chronyc authdata
sudo chronyc ntpdata
sudo systemctl status chrony

Check for NTS-specific information in the sources output:

sudo chronyc sources -v | grep -i nts

View recent log entries to ensure NTS authentication is working:

sudo tail -f /var/log/chrony/tracking.log
sudo journalctl -u chrony -f
Note: NTS authentication may take a few minutes to establish after starting chrony. Look for "NTS" indicators in the chronyc sources output to confirm encrypted synchronization.

Common issues

SymptomCauseFix
No NTS sources visible NTS servers unreachable or certificates invalid Check firewall rules and verify NTS server availability with telnet time.cloudflare.com 4460
Certificate validation errors System clock too far off or CA certificates outdated Manually sync time first with sudo ntpdate -s time.nist.gov then restart chrony
chrony fails to start Permission errors on NTS directory Fix ownership with sudo chown -R chrony:chrony /var/lib/chrony/nts
NTS authentication timeout Firewall blocking port 4460 Verify port 4460/tcp is open and accessible
High stratum number NTS servers not responding Add fallback NTP servers and check network connectivity
Never disable certificate verification. If you encounter certificate issues, fix the underlying problem rather than disabling security features.

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Nie chcesz zarządzać tym samodzielnie?

Zarządzamy infrastrukturą firm, które zależą od dostępności. W pełni zarządzana, z jednym stałym kontaktem, który zna Twoje środowisko.

Macie jednego stałego opiekuna, który zna Waszą konfigurację

Rotterdam 04:19 · dostępny w wiadomości, bez formularza zgłoszeń