rkik
CLI tool designed for stateless and passive NTP inspection, just as dig or ping are for DNS and ICMP. It supports async requests and continuous monitoring.
rkik - Rusty Klock Inspection Kit
Think
dig, but for time sources. No daemon, no root, no config to touch.
rkik queries NTP, NTS, and PTP servers and tells you what they say — offset, RTT, stratum, authentication status. One shot, stateless, done.
Why rkik?
- Passive by design. It never touches your system clock unless you explicitly ask (
--sync). Run it anywhere, as anyone. - NTS that actually works. rkik-nts 1.0.0 is the first CLI implementation of RFC 8915 verified against real public servers (
time.cloudflare.com,nts.ntp.se). Older tools either skip authentication or implement it wrong. - Three protocols, one tool. NTP over IPv4/IPv6, NTS with full TLS diagnostics, and PTP/IEEE 1588 — all with compare mode, JSON output, and Nagios/Centreon plugin support.
Demo
$ rkik --nts time.cloudflare.com -v
Server: time.cloudflare.com [NTS Authenticated]
IP: 162.159.200.1:123
UTC Time: Tue, 28 Apr 2026 14:32:10 +0000
Local Time: 2026-04-28 16:32:10
Clock Offset: 1.243 ms
Round Trip Delay: 14.871 ms
=== NTS-KE Diagnostics ===
Handshake Duration: 87.342 ms
Cookies Received: 8 cookies
AEAD Algorithm: AEAD_AES_SIV_CMAC_256
NTP Server: 162.159.200.1:123
=== TLS Certificate ===
Subject: CN=time.cloudflare.com
Issuer: C=US, O=DigiCert Inc, CN=GeoTrust TLS ECC CA G1
Valid: 2025-02-10 → 2026-03-12
Fingerprint (SHA-256): 4b060f4d...462119
SANs: time.cloudflare.com
Installation
cargo install rkik
Arch Linux (AUR):
yay -S rkik-git
Nix / NixOS:
nix shell nixpkgs#rkik
DEB / RPM / tar.gz: grab the latest from GitHub Releases.
# Debian / Ubuntu
sudo apt install ./rkik_2.1.0-1_amd64.deb
# Fedora / RHEL / Alma / Rocky
sudo dnf install rkik-2.1.0-1.x86_64.rpm
Quick start
# Basic NTP probe
rkik pool.ntp.org
# NTS — cryptographically authenticated
rkik --nts time.cloudflare.com
# Compare a few servers side by side
rkik --compare pool.ntp.org time.google.com time.cloudflare.com
# Plugin output for Nagios / Centreon / Zabbix
rkik pool.ntp.org --plugin --warning 50 --critical 200
# JSON, prettified
rkik pool.ntp.org --json --pretty
NTP
rkik time.google.com # basic probe
rkik time.google.com -v # adds stratum, ref ID
rkik time.google.com --count 10 --interval 2 # repeat 10 times
rkik -6 pool.ntp.org # IPv6-only resolution
Output:
Server: time.google.com
IP: 216.239.35.4:123
UTC Time: Tue, 28 Apr 2026 14:32:08 +0000
Local Time: 2026-04-28 16:32:08
Clock Offset: 0.312 ms
Round Trip Delay: 9.449 ms
NTS — Network Time Security ★
NTS (RFC 8915) is authenticated NTP — every packet is verified with AEAD encryption, so you know the response hasn't been tampered with.
rkik --nts time.cloudflare.com # authenticated probe
rkik --nts time.cloudflare.com -v # with TLS/KE diagnostics
rkik --nts --compare nts.ntp.se time.cloudflare.com
When something goes wrong, rkik tells you what kind of failure it is:
| Kind | Meaning |
|---|---|
aead_failure |
AEAD verification failed — possible tampering |
missing_authenticator |
Authenticator extension absent in response |
unauthenticated_response |
Server completed NTS-KE but sent plain NTP |
ke_handshake_failed |
TLS or NTS-KE handshake failed |
timeout |
Connection timed out |
Security-critical failures (aead_failure, missing_authenticator, unauthenticated_response, invalid_unique_id, invalid_origin_timestamp) exit with code 2 in plugin mode.
See docs/user-guide.md#nts for the full error reference.
PTP — Precision Time Protocol
PTP mode (IEEE 1588-2019) is Linux-only and requires the ptp feature (on by default).
rkik --ptp 192.0.2.10
rkik --ptp --ptp-domain 24 --ptp-event-port 3319 --ptp-general-port 3320 127.0.0.1
rkik --ptp --compare 192.168.1.100 192.168.1.101 --format json
See docs/user-guide.md#ptp for flags and output format.
Plugin mode
rkik time.google.com --plugin --warning 50 --critical 200
# → RKIK OK - offset 4.006ms rtt 9.449ms from time.google.com (216.239.35.4) | offset_ms=4.006ms;50;200;0; rtt_ms=9.449ms;;;0;
Exit codes: 0 OK · 1 WARNING · 2 CRITICAL · 3 UNKNOWN (request failed or security error)
Debugging a time issue
Your monitoring fires a time alert on ntp.server.local. You don't know yet whether the problem is that server or its upstream.
$ rkik ntp.server.local -v
Clock Offset: 5000.145 ms
Reference ID: 145.238.80.80
Five seconds of drift, and you can see the upstream. Check it directly:
$ rkik 145.238.80.80
Clock Offset: 5001.531 ms
Same offset upstream. The problem isn't your server — it's the reference. Time to point it somewhere else.
For developers
rkik is split into a library and a CLI. The library has no clap, no process::exit, no terminal code — just async functions you can call directly.
[dependencies]
rkik = { version = "2", default-features = false, features = ["json"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
use rkik::query_one;
use std::time::Duration;
let r = query_one("time.google.com", false, Duration::from_secs(3), false, 4460).await?;
println!("{}: offset={:.3}ms", r.target.name, r.offset_ms);
Full API reference, architecture overview, and contribution guide: docs/developer-guide.md
To contribute, see CONTRIBUTING — issues labelled good first issue are a good starting point.