Best Practices for Selecting and Configuring NTP Servers: A Complete Guide to NTS Security
Use 4 to 10 geographically diverse, non-virtualized NTS-capable servers and validate connectivity with automated scripts before deployment.
Accurate time synchronization is foundational to system security and operational integrity, particularly when protecting against man-in-the-middle attacks using the Network Time Security (NTS) protocol. The jauderho/nts-servers repository provides a curated reference implementation that codifies industry best practices for selecting and configuring NTP servers with end-to-end encryption. Following these guidelines ensures your infrastructure maintains precise, authenticated time while minimizing vulnerability to spoofing or jitter-induced drift.
Use 4 to 10 Time Sources for Optimal Resilience
Configuring too few time sources creates a single point of failure, while configuring too many generates unnecessary network traffic and load. According to the jauderho/nts-servers source code, the optimal range is between 4 and 10 time sources to balance redundancy with efficiency.
In README.md at lines 24-25, the repository explicitly recommends this range to improve resilience without excessive network chatter. This guideline aligns with the NTP best practice of allowing the intersection algorithm to discard outliers while maintaining quorum even if one or two sources become unreachable.
Prioritize NTS-Only Configurations
The Network Time Security (NTS) protocol encrypts NTP traffic and authenticates timestamps, preventing attackers from manipulating your system clock through spoofed packets. When configuring your time infrastructure, never mix unencrypted NTP with encrypted NTS endpoints on the same client.
As documented in README.md at lines 25-26, NTP and NTS cannot be mixed in the same configuration. The nts-servers repository enforces this by listing only NTS-capable servers, ensuring that all generated configuration files maintain cryptographically authenticated time synchronization.
Exclude Virtualized Infrastructure
Virtualization introduces unpredictable jitter and clock drift because the hypervisor schedules CPU time across multiple guests. For high-precision timekeeping, you should avoid servers running on virtualized platforms.
The repository's README.md at lines 26-30 specifically warns that "virtualized systems do not make for good time sources" and segregates these into a dedicated table. When selecting providers, prefer bare-metal infrastructure or specialized timing hardware that minimizes variable latency.
Validate NTS Connectivity Before Deployment
Adding unresponsive or misconfigured servers to your chrony.conf degrades synchronization quality and startup times. Always verify that a server actually supports NTS handshakes before including it in your rotation.
The repository includes scripts/ntsCheck.sh, a Bash validation tool that performs a one-shot NTS probe using:
chronyd -Q -t 5 "server $NTS_SERVER iburst nts maxsamples 1"
This command attempts a five-second NTS handshake with the target server. A successful exit code (0) confirms the server supports NTS and is reachable, while any non-zero exit indicates the server should not be added to your configuration.
Leverage Anycast and Geographic Diversity
Network latency directly impacts time accuracy, so selecting servers close to your infrastructure reduces round-trip delay. Additionally, anycast addresses provide automatic failover by routing to the nearest available endpoint.
The nts-sources.yml file in the repository includes anycast entries such as time.cloudflare.com alongside geographically distributed sources spanning Brazil to Sweden. This diversity ensures that regional outages or network partitions do not isolate your systems from valid time sources.
Automated Configuration Management
Manual editing of NTP configuration files introduces drift between your source list and deployed configurations. The jauderho/nts-servers repository implements a single source of truth pattern to eliminate this risk.
The Canonical Data Source
All server metadata resides in nts-sources.yml, a structured YAML file containing hostnames, stratum levels, locations, and ownership information. This file serves as the authoritative registry for all NTS-capable servers in the project.
Configuration Generation
The scripts/ntpServerConverter.py utility reads nts-sources.yml and automatically generates two target configuration formats:
chrony.conffor the Chrony daemonntp.tomlfor the Rust-basedntpd-rsimplementation
Run the converter after any edit to nts-sources.yml:
./scripts/ntpServerConverter.py nts-sources.yml
This workflow guarantees consistency across different NTP implementations and eliminates human error in transcribing server addresses.
Deployment Examples
The generated chrony.conf entries follow this format:
server time.cloudflare.com iburst nts maxsamples 1
server 1.ntp.ubuntu.com iburst nts maxsamples 1
For ntpd-rs, the equivalent ntp.toml configuration appears as:
[[servers]]
address = "time.cloudflare.com"
iburst = true
nts = true
maxsamples = 1
[[servers]]
address = "1.ntp.ubuntu.com"
iburst = true
nts = true
maxsamples = 1
System administrators copy these generated files to /etc/chrony/chrony.conf or /etc/ntpd/ntp.conf to activate the vetted NTS pool.
Summary
- Maintain 4-10 time sources to ensure quorum without network congestion, as specified in the repository's
README.md. - Use NTS exclusively and never mix unencrypted NTP traffic with encrypted sessions.
- Avoid virtualized servers which introduce timing jitter that degrades accuracy.
- Validate every server using
scripts/ntsCheck.shbefore submitting pull requests or deploying to production. - Prefer anycast and geographically diverse sources to minimize latency and maximize redundancy.
- Automate configuration generation using
scripts/ntpServerConverter.pyto maintain consistency betweennts-sources.ymland your daemon configurations.
Frequently Asked Questions
How many NTP servers should I configure for optimal time accuracy?
You should configure between 4 and 10 NTP servers. This range provides sufficient redundancy for the NTP intersection algorithm to identify and discard falsetickers while preventing excessive network overhead that occurs with larger pools.
What is the difference between NTP and NTS?
NTP (Network Time Protocol) transmits timestamps in plaintext, making it vulnerable to man-in-the-middle attacks that can shift your system clock. NTS (Network Time Security) adds TLS-based encryption and authentication to NTP packets, ensuring that your client receives unmodified timestamps from legitimate servers. The jauderho/nts-servers repository supports only NTS-capable endpoints.
Why should I avoid virtualized NTP servers?
Virtualized environments share physical CPU resources across multiple guests through a hypervisor scheduler, introducing variable latency known as jitter. This jitter degrades the precision of time measurements because the virtual machine cannot guarantee consistent packet timestamping, whereas bare-metal servers provide deterministic timing essential for sub-millisecond accuracy.
How do I verify that a server supports NTS before adding it?
Use the scripts/ntsCheck.sh validation script included in the repository. This tool executes a test query using chronyd -Q -t 5 with the NTS flag enabled. If the server responds successfully within five seconds with a valid NTS handshake, the script exits with code 0 and you can safely add the server to nts-sources.yml.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →