How to Configure ntp.toml for ntpd-rs with NTS Servers

To configure ntp.toml for ntpd-rs with NTS servers, populate [[source]] tables with mode = "nts" and the server address, then point ntpd-rs to the file via --config or the NTPD_RS_CONFIG environment variable.

The jauderho/nts-servers repository maintains a curated, auto-generated ntp.toml file specifically for ntpd-rs, a modern Rust-based NTP daemon. This configuration enables secure time synchronization using Network Time Security (NTS), eliminating the need to manually compile server lists or risk configuration drift.

Understanding the ntp.toml Configuration Structure

The ntp.toml file uses TOML format with a series of [[source]] tables. Each table represents a single NTS-enabled time server that ntpd-rs will contact.

A minimal entry requires two fields:

[[source]]
mode = "nts"
address = "time.cloudflare.com"

The mode = "nts" parameter instructs ntpd-rs to perform an NTS-KE (Key Establishment) handshake and use authenticated NTP packets. The address field accepts any NTS-enabled hostname. According to the repository's generate_ntp_toml function in scripts/ntpServerConverter.py (lines 86-104), each server from the master data file is emitted as a separate [[source]] block in this exact format.

Generating ntp.toml from the nts-servers Repository

Rather than maintaining ntp.toml manually, the repository provides an automated pipeline that generates the configuration from a canonical data source.

The nts-sources.yml Data Source

The authoritative list of servers resides in nts-sources.yml at the repository root. This YAML file contains metadata for each server including hostname, stratum, location, owner, and a vm flag indicating virtualized infrastructure. When servers are added or updated here, the downstream configuration files automatically reflect those changes.

The ntpServerConverter.py Script

The Python script scripts/ntpServerConverter.py reads nts-sources.yml and produces three artifacts: a Markdown server list, a chrony.conf, and the ntp.toml file. The generation logic specifically filters for NTS-capable entries and formats them into the required TOML structure.

To regenerate the configuration:


# From the repository root

./scripts/ntpServerConverter.py nts-sources.yml

This command outputs:

Always run git diff after regeneration to verify that only the intended files changed, as recommended in the repository documentation.

Configuring ntpd-rs to Use Your ntp.toml

Once you have generated or manually created ntp.toml, you must ensure ntpd-rs can locate and parse it at startup.

File Placement

The standard system location for ntpd-rs configuration is /etc/ntpd-rs/ntp.toml. Copy the generated file there:

sudo cp ntp.toml /etc/ntpd-rs/ntp.toml
sudo chmod 644 /etc/ntpd-rs/ntp.toml

Command-Line and Environment Options

If you prefer to keep the configuration in a custom location, ntpd-rs accepts the --config flag:

ntpd-rs --config /path/to/ntp.toml

Alternatively, set the NTPD_RS_CONFIG environment variable:

export NTPD_RS_CONFIG=/path/to/ntp.toml
ntpd-rs

Starting the Daemon

For production use, enable and start the systemd service:

sudo systemctl enable --now ntpd-rs

For testing or debugging, run the daemon manually in the foreground to verify it parses the configuration correctly:

ntpd-rs --config ntp.toml

Best Practices for NTS Server Selection

The jauderho/nts-servers repository enforces specific constraints to ensure reliable and secure time synchronization.

Server Quantity Limits

Configure at least 4 and no more than 10 distinct NTS servers. This range provides sufficient redundancy for Byzantine fault tolerance while avoiding excessive network load and NTS-KE handshake overhead.

Avoid Mixed Modes

Do not mix classic NTP (mode = "client") with NTS entries in the same ntp.toml file. The repository specifically generates NTS-only configurations, and ntpd-rs handles authentication parameters differently for each mode.

Virtualized Host Considerations

Entries marked with vm: true in nts-sources.yml indicate virtualized infrastructure. These servers may exhibit higher jitter due to hypervisor scheduling and are grouped separately in the generated TOML. Use them as supplementary sources rather than primary timekeepers.

Anycast Limitations

Many public NTS servers use Anycast routing (e.g., Cloudflare). While this improves availability, refer to RFC 8633 section 4.3 for potential limitations regarding path asymmetry and certificate validation in Anycast deployments.

Verifying NTS Authentication

After starting ntpd-rs with your ntp.toml, confirm that NTS handshakes are succeeding.

Use the ntpq utility to inspect peer status:

ntpq -p -c "ntp server"

Look for the N flag in the remote column, which indicates successful NTS authentication. If the flag is absent, verify that the server supports NTS and that your firewall allows TCP port 4460 (NTS-KE) and UDP port 123 (NTP).

Summary

  • The ntp.toml file uses [[source]] tables with mode = "nts" and an address field to define NTS servers for ntpd-rs.
  • The jauderho/nts-servers repository auto-generates this file from nts-sources.yml using scripts/ntpServerConverter.py (specifically the generate_ntp_toml function at lines 86-104).
  • Deploy the configuration to /etc/ntpd-rs/ntp.toml, or specify a custom path via --config or the NTPD_RS_CONFIG environment variable.
  • Maintain 4 to 10 NTS sources for optimal security and reliability, avoiding mixed-mode configurations.
  • Verify NTS operation using ntpq and look for the N authentication flag.

Frequently Asked Questions

How do I add a new NTS server to my ntp.toml configuration?

Edit the nts-sources.yml file in the repository root to include the new server details (hostname, stratum, location, owner), then run ./scripts/ntpServerConverter.py nts-sources.yml to regenerate ntp.toml. This ensures the new server appears with the correct mode = "nts" syntax and maintains consistency across all generated configuration files.

Can I mix NTS servers with standard NTP servers in the same ntp.toml file?

No, you should not mix mode = "nts" entries with mode = "client" (standard NTP) in the same configuration. The jauderho/nts-servers repository generates NTS-only configurations, and ntpd-rs handles authentication and certificate validation specifically for NTS mode. Mixing modes may cause configuration parsing errors or unexpected security behavior.

Configure between 4 and 10 NTS servers. The repository documentation specifies a minimum of 4 servers to provide adequate redundancy and protection against Byzantine faults, while limiting the maximum to 10 prevents excessive network overhead from NTS-KE handshakes and certificate exchanges. This range balances reliability with performance.

How do I verify that ntpd-rs is actually using NTS authentication?

Use the ntpq utility with the command ntpq -p -c "ntp server" and examine the output for the N flag in the remote column. This flag indicates that the server connection is using NTS authentication. If the flag is missing, verify that the server supports NTS, that your firewall allows TCP port 4460 (for NTS-KE), and that the mode = "nts" setting is correctly specified in your ntp.toml file.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →