17 releases (9 stable)
Uses new Rust 2024
| new 2.2.1 | May 13, 2026 |
|---|---|
| 2.1.0 | Jan 24, 2026 |
| 2.0.0 | Dec 16, 2025 |
| 1.2.1 | Nov 25, 2025 |
| 0.6.0 | Jul 30, 2025 |
#464 in Network programming
3,241 downloads per month
125KB
3K
SLoC
rkik - Rusty Klock Inspection Kit
Think
dig, but for time sources. No daemon, no root, no config to touch.
rkik queries NTP and NTS 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 Rust implementation of RFC 8915 verified against real public servers (
time.cloudflare.com,nts.ntp.se). Older tools either skip authentication or implement it wrong. - Two protocols, one tool. NTP over IPv4/IPv6 and NTS with full TLS diagnostics — compare mode, JSON output, and Nagios/Centreon plugin support included.
- The only NTS-aware monitoring plugin for Nagios, Centreon and Zabbix
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.2.0-1_amd64.deb
# Fedora / RHEL / Alma / Rocky
sudo dnf install rkik-2.2.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.
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.
Dependencies
~11–26MB
~272K SLoC