esc
move open

sdns.

A recursive DNS resolver with DNSSEC validation, written in Go. It resolves from the root, serves DoT, DoH and DoQ alongside plain UDP/TCP, and answers warm cache hits from the bytes it already holds.

a warm cache hit, validated
$ dig @127.0.0.1 example.com A +dnssec +multiline

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41022
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2

;; ANSWER SECTION:
example.com.  3600 IN A     93.184.215.14
example.com.  3600 IN RRSIG A 13 2 3600 (...)

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)

Throughput and cost, with the conditions attached

Every figure below was produced by a documented run on one host, against the same corpus, with the methodology and the fairness notes written down. Read how they were taken before you trust them.

424k/s
UDP, cached answers
median, 3×20 s, -c 128 -T 8
226k/s
TCP, cached answers
median, 5×20 s, -c 20 -T 4
0
allocations per wire-served hit
pinned by a test in CI
658/s
cold resolution, 50k names
empty cache, as shipped

sdns 1.8.0 at 8b36b91, 2×Xeon E5-2620 v4 (32 logical cores). The cold figure is the configuration sdns ships, with QNAME minimisation on; turning it off measures 905/s and gives up privacy the resolver is meant to keep. Methodology, tuning of each contender, and the raw tables →

Same host, same corpus, same day

Each contender was given a reasonable configuration, not an exhaustive tuning pass. PowerDNS answers these from its packet cache — its lightest path, as this is ours.

ResolverUDP medianTCP median
sdns 1.8.0424k226k
PowerDNS Recursor 5.4.1371k56k
Unbound 1.24.2343k136k
Knot Resolver 6.2.0191k142k

What is implemented

Standards the resolver implements, not a list of things it is aware of.

RFC 4035DNSSEC validation
RFC 5011Trust anchor updates
RFC 6147DNS64 synthesis
RFC 6672DNAME redirection
RFC 7858DNS over TLS
RFC 7871EDNS Client Subnet
RFC 7873DNS cookies
RFC 2308Negative caching
RFC 6303Locally served zones
RFC 8020NXDOMAIN cuts the subtree
RFC 8198Aggressive NSEC use
RFC 8484DNS over HTTPS
RFC 8767Serve stale on failure
RFC 8806Local root zone
RFC 8914Extended DNS errors
RFC 8976ZONEMD verification
RFC 9156QNAME minimisation
RFC 9250DNS over QUIC
RFC 9520Caching resolution failures
draft-vixieResponse Policy Zones

A working configuration is short

sdns writes a complete, commented configuration on first run. Most deployments change a handful of its lines and leave the rest — these three are the ones worth reading first.

# three lines of the generated file

bind = ":53"
dnssec = "on"

# The default allows everyone. Narrow it
# before binding to a reachable address.
accesslist = ["192.168.0.0/16"]
  • Everything new ships off or in shadow. Enabling a feature is a decision you make, never one made for you by an upgrade.
  • sdns -t judges the whole file and reports every problem at once — addresses, CIDRs, enumerations, TLS files, policy zones — with the same loaders the server runs.
  • A key no setting claims fails the test and only warns at startup, so a stale key from an older version cannot become an outage.

Full configuration reference →

Current state

v1.8.2
Release
Stars
Forks
Open issues & PRs
Go
Language
MIT
License

Beyond resolving

Response Policy Zones

Name, client-address and answer-address triggers; file and TSIG-signed AXFR feeds; a shadow mode whose counters predict what enforcement would do.

Local root zone

The root served from a ZONEMD-verified local copy, refreshed on its own SOA schedule. Referrals and junk-TLD denials cost no upstream query.

Recursion firewall

Per-request-tree budgets on outbound queries, internal work and DNSSEC operations, with shadow and enforce modes.

Serve stale

An expired answer as a last resort when resolution fails, always bounded by the delegation lease the parent granted.

Views and forwarding

Static answers scoped to client networks, and per-zone conditional forwarding to their own upstreams.

Middleware and plugins

The query path is a chain of middlewares; external plugins load into it without forking the server.

64 metrics

Cache, resolution, DNSSEC work, ingress, policy — each with its labels documented, and the PromQL to answer the questions operators actually ask.