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

> Learn to configure ntp.toml for ntpd-rs with NTS servers. Simply set mode to nts and provide server addresses for secure NTP synchronization. Configure via file or environment variable.

- Repository: [Jauder Ho/nts-servers](https://github.com/jauderho/nts-servers)
- Tags: how-to-guide
- Published: 2026-03-04

---

**To configure [`ntp.toml`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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:

```toml
[[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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntpServerConverter.py) reads [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) and produces three artifacts: a Markdown server list, a [`chrony.conf`](https://github.com/jauderho/nts-servers/blob/main/chrony.conf), and the [`ntp.toml`](https://github.com/jauderho/nts-servers/blob/main/ntp.toml) file. The generation logic specifically filters for NTS-capable entries and formats them into the required TOML structure.

To regenerate the configuration:

```bash

# From the repository root

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

```

This command outputs:
- [`README.md`](https://github.com/jauderho/nts-servers/blob/main/README.md) (updated server table)
- [`chrony.conf`](https://github.com/jauderho/nts-servers/blob/main/chrony.conf) (for Chrony users)
- [`ntp.toml`](https://github.com/jauderho/nts-servers/blob/main/ntp.toml) (for ntpd-rs users)

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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main//etc/ntpd-rs/ntp.toml). Copy the generated file there:

```bash
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:

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

```

Alternatively, set the `NTPD_RS_CONFIG` environment variable:

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

```

### Starting the Daemon

For production use, enable and start the systemd service:

```bash
sudo systemctl enable --now ntpd-rs

```

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

```bash
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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/ntp.toml), confirm that NTS handshakes are succeeding.

Use the `ntpq` utility to inspect peer status:

```bash
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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml)** using **[`scripts/ntpServerConverter.py`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntpServerConverter.py)** (specifically the `generate_ntp_toml` function at lines 86-104).
- Deploy the configuration to **[`/etc/ntpd-rs/ntp.toml`](https://github.com/jauderho/nts-servers/blob/main//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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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.

### What is the recommended number of NTS servers to configure in ntp.toml?

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`](https://github.com/jauderho/nts-servers/blob/main/ntp.toml) file.