RCVD: Introduction
RCVD (Resilient, Cryptographic, Verifiable DNS) is a privacy-first DNS engine: one static Go binary, encrypted transports only, and a hard guarantee that no query ever leaves the host in plaintext.
The problem
Getting private DNS on Linux, BSD, or macOS today means assembling a mosaic of single-purpose programs: a stub encryptor, a validating resolver, a blocklist proxy, a cache. Each brings its own configuration and its own failure modes — and, critically, its own willingness to fall back to plaintext DNS when an encrypted path fails. The resulting stack is hard to reason about, and none of the pieces gives you a first-class guarantee that a query left the host encrypted.
I wanted one tool that just does the right thing and never leaks.
What RCVD does
RCVD integrates, under one configuration:
Encrypted transports — DNS-over-QUIC (RFC 9250), DNS-over-TLS (RFC 7858), and DNS-over-HTTPS (RFC 8484, over both HTTP/2 and HTTP/3).
Multi-upstream fallback — an ordered, health-aware chain of encrypted upstreams. If one is down, it moves to the next.
DNSSEC validation — full cryptographic verification against the IANA root trust anchors; responses that fail validation become SERVFAIL.
Verifiable upstream trust — beyond ordinary CA validation, an upstream can be bound to a specific server key with an SPKI public-key pin (
pinned_pubkey). The connection is refused unless the key matches, so trust in the deploment does not have to rest on the CA system alone.Automatic certificates — when RCVD serves encrypted DNS to others (Mode 2), it can obtain and renew real certificates automatically over ACME (Let’s Encrypt), so a browser-trusted DoH/DoT/DoQ endpoint needs no manual cert wrangling.
Caching and blocklists — an in-memory cache with admin-selectable cache types, plus domain and hosts-format blocklists with wildcard support.
Two modes from one binary — a forwarder (Mode 1) that accepts local or LAN DNS and encrypts it outbound, and an upstream service (Mode 2) that exposes encrypted DoH/DoT/DoQ endpoints to other resolvers and to web browsers. A single process can run both and share one warm cache across them.
The one non-negotiable principle
No query leaves the host in plaintext. If every configured encrypted transport fails, RCVD returns SERVFAIL — it never falls back to cleartext.
This is enforced at every error path, not offered as a configurable policy. It’s a deliberate divergence from RFC 9250 §5.2, which permits a DoQ client to fall back to DoT and then “potentially cleartext.” RCVD does the fall back to DoT and DoH — but never the fall back to cleartext. Port 53, when used at all, is silent or encrypted; it is never a plaintext egress.
Why an Admin wants this
If you’ve ever run tcpdump and watched DNS leak in plaintext despite thinking you
had encryption configured, this is the tool that removes that class of problem. You
get one ‘WireGuard-style’ binary, reuseable, deployment-specific config files,
no runtime dependencies, and a guarantee you can actually verify — with built-in
--verify-upstream, --audit, and --stats commands that report posture without
ever recording what was queried.
That last point matters for a tool that has to answer to both users and auditors: you can prove the encryption posture is what you claim it is, without ever building the query log that would betray the people you’re supposed to be protecting. The same binary drops onto a laptop, a router, or a container the same way — copy it in, point it at a config, and it has no interpreter, no library tree, and no package manager to keep patched. On a busy resolver that stays healthy through upstream trouble on its own: a warm shared cache serves repeat lookups instantly, and if an encrypted upstream degrades it fails over to the next without a hiccup — and without ever quietly reaching for plaintext to “keep things working.”
Read more
- Project site: rcvd.net
- Whitepaper (the full, factual design + implementation): rcvd.net/whitepaper
- Field notes from running it on a real router: see the Field Notes page in this section.