Recursive resolver

Full iterative resolution from root hints. CNAME chain following with loop detection. Configurable recursion depth. QNAME minimization (RFC 9156) is on by default.

Optionally run as a forwarder to upstream resolvers (Cloudflare, Google, Quad9) — same binary, configuration-driven.

[resolver]
forwarders = []
dnssec = true
qname_minimization = true
max_recursion_depth = 30

Authoritative server

Serve zones from RFC 1035 zone files, or from a PostgreSQL backend for ISP/enterprise scale. PostgreSQL LISTEN/NOTIFY drives hot zone reloads without restart.

Run authoritative-only, recursive-only, or both in the same process.

[authoritative]
source = "database"

[authoritative.database]
connection = "postgresql://rdns:..."

DNS-over-TLS

RFC 7858 encrypted DNS on port 853. TLS provided by rustls — no OpenSSL in the binary, no OpenSSL CVEs to track.

[listeners.tls]
addresses = ["0.0.0.0:853"]
cert = "/etc/rdns/tls/cert.pem"
key  = "/etc/rdns/tls/key.pem"

DNSSEC validation

Chain of trust verification from root trust anchors. Disable per-query if needed; validated by default.

[resolver]
dnssec = true

RPZ filtering

Block or redirect domains via Response Policy Zones (BIND-compatible). Use for ad blocking, malware filtering, or parental controls.

[[rpz.zones]]
name = "rpz.local"
file = "/etc/rdns/rpz/blocklist.rpz"

Sharded cache with serve-stale

256-shard concurrent cache built on parking_lot::RwLock. Cache hits take read locks only — no contention between workers. Negative caching, TTL bounds, and RFC 8767 serve-stale for graceful degradation during upstream outages.

[cache]
max_entries = 1_000_000
serve_stale = true
stale_max_ttl = 86400
stale_answer_ttl = 30

Control CLI

Unix socket control interface. Flush the whole cache, flush a single name, dump stats — all without touching the running daemon's config.

rdns-control stats
rdns-control flush-cache
rdns-control flush-name example.com

Prometheus metrics

Per-listener QPS, cache hit rates, latency histograms, upstream resolution stats — all exposed at /metrics in Prometheus exposition format. Drop into your existing Grafana stack.

[metrics]
enabled = true
address = "127.0.0.1:9153"

Security hardening

Privilege dropping after bind. FreeBSD Capsicum capability sandbox. PID file management. Single-instance enforcement via filesystem lock. Rate limiting per source.

[security]
sandbox = true
rate_limit = 1000

[server]
user  = "rdns"
group = "rdns"

Get rDNS running in 60 seconds.

Single static binary. TOML config. MIT licensed. Linux, FreeBSD, and macOS.