Skip to content

aguacero7/rkik

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

146 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rkik - Rusty Klock Inspection Kit

Build & Tests crates.io Packaging status

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

asciicast

$ 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

Packaging status


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.

Packages

 
 
 

Contributors

Languages