SDNS

A high-performance, recursive DNS resolver server with DNSSEC support, focused on preserving privacy.

This project is maintained by semihalev

SDNS :rocket:

A high-performance, recursive DNS resolver server with DNSSEC support, focused on preserving privacy.


Installation

Install SDNS using the go install command:

go install github.com/semihalev/sdns@latest

Pre-built Binaries

Download the latest release from the GitHub Releases page.

Docker

$ docker run -d --name sdns -p 53:53 -p 53:53/udp sdns

Docker Compose

Install docker-compose and run from the root directory:

$ sudo apt install docker-compose
$ docker-compose up -d

Homebrew for macOS

Install and run as a service:

$ brew install sdns
$ brew install semihalev/tap/sdns (updated every release)
$ brew services start sdns

Snapcraft

$ snap install sdns

AUR for ArchLinux

$ yay -S sdns-git

Note: Pre-built binaries, Docker packages, brew taps, and snaps are automatically created by GitHub workflows.

Building from Source

$ go build

Testing

$ make test

Flags

Flag Description
-c, –config PATH Location of the config file. If it doesn’t exist, a new one will be generated
-v, –version Show the SDNS version
-h, –help Show help information and exit

Debugging Environment

To debug your environment, execute the following command:

$ export SDNS_DEBUGNS=true && export SDNS_PPROF=true && ./sdns

The SDNS_DEBUGNS environment variable is beneficial for verifying the RTT (Round Trip Time) of authoritative servers. To use it, send an HINFO query for zones with chaos class.

Here’s an example of the output you might receive:

$ dig chaos hinfo example.com

; <<>> DiG 9.17.1 <<>> chaos hinfo example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29636
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: f27dbb995df5ac79e4fa37c07d131b5bd03aa1c5f802047a7c02fb228a886cb281ecc319323dea81 (good)
;; QUESTION SECTION:
;example.com.			CH	HINFO

;; AUTHORITY SECTION:
example.com.		0	CH	HINFO	"Host" "IPv4:199.43.135.53:53 rtt:142ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv4:199.43.133.53:53 rtt:145ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv6:[2001:500:8f::53]:53 rtt:147ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv6:[2001:500:8d::53]:53 rtt:148ms health:[GOOD]"

Configuration (v1.5.0)

Key Description
version Configuration file version
directory Working directory for SDNS data storage. Must be writable by the SDNS process. Default: “db”
bind DNS server binding address and port. Default: “:53”
bindtls DNS-over-TLS (DoT) server binding address. Default: “:853”
binddoh DNS-over-HTTPS (DoH) server binding address. Default: “:8053”
binddoq DNS-over-QUIC (DoQ) server binding address. Default: “:853”
tlscertificate Path to the TLS certificate file for DoT/DoH/DoQ
tlsprivatekey Path to the TLS private key file for DoT/DoH/DoQ
outboundips Outbound IPv4 addresses for DNS queries. Multiple addresses enable random source IP selection per request
outboundip6s Outbound IPv6 addresses for DNS queries. Multiple addresses enable random source IP selection per request
rootservers Root DNS servers (IPv4). These are the authoritative name servers for the DNS root zone
root6servers Root DNS servers (IPv6). These are the authoritative name servers for the DNS root zone
dnssec Enable DNSSEC validation for secure DNS responses. Options: “on” or “off”. Default: “on”
rootkeys DNSSEC root zone trust anchors in DNSKEY format
fallbackservers Upstream DNS servers used when all others fail. Format: “IP:port” (e.g., “8.8.8.8:53”)
forwarderservers Forward all queries to these DNS servers. Format: “IP:port” (e.g., “8.8.8.8:53”)
api HTTP API server binding address for statistics and control. Leave empty to disable
bearertoken API bearer token for authorization. If set, Authorization header must be included in API requests
blocklists URLs of remote blocklists to download and use for filtering
blocklistdir [DEPRECATED] Blocklist directory. Now automatically created in the working directory
loglevel Logging verbosity level. Options: crit, error, warn, info, debug. Default: “info”
accesslog Path to the access log file in Common Log Format. Leave empty to disable
nullroute IPv4 address returned for blocked A queries. Default: “0.0.0.0”
nullroutev6 IPv6 address returned for blocked AAAA queries. Default: “::0”
accesslist IP addresses/subnets allowed to make queries. Default allows all: [“0.0.0.0/0”, “::0/0”]
querytimeout Maximum time to wait for any DNS query to complete. Default: “10s”
timeout Network timeout for upstream DNS queries. Default: “2s”
hostsfile Path to hosts file (RFC 952/1123 format) for local resolution. Leave empty to disable
expire Cache TTL for error responses in seconds. Default: 600
cachesize Maximum number of cached DNS records. Default: 256000
prefetch Prefetch threshold percentage (10-90). Refreshes popular cache entries before expiration. 0 disables
maxdepth Maximum recursion depth for queries. Prevents infinite loops. Default: 30
ratelimit Global query rate limit per second. 0 disables. Default: 0
clientratelimit Per-client rate limit per minute. 0 disables. Default: 0
domainmetrics Enable per-domain query metrics collection. Default: false
domainmetricslimit Maximum number of domains to track in metrics. 0 = unlimited (use with caution). Default: 10000
blocklist Manual domain blocklist. Domains listed here will be blocked
whitelist Manual domain whitelist. Overrides blocklist matches
cookiesecret DNS cookie secret (RFC 7873) for client verification. Auto-generated if not set
nsid DNS server identifier (RFC 5001) for identifying this instance. Leave empty to disable
chaos Enable responses to version.bind and hostname.bind chaos queries. Default: true
qname_min_level QNAME minimization level (RFC 7816). 0 disables. Higher values increase privacy but may impact performance
emptyzones Enable local authoritative responses for RFC 1918 zones. See http://as112.net/ for details
tcpkeepalive Enable TCP connection pooling for root and TLD servers. Improves performance by reusing connections. Default: false
roottcptimeout TCP idle timeout for root server connections. Default: “5s”
tldtcptimeout TCP idle timeout for TLD server connections (com, net, org, etc.). Default: “10s”
tcpmaxconnections Maximum number of pooled TCP connections. 0 uses default. Default: 100
dnstapsocket Unix domain socket path for dnstap binary DNS logging. Leave empty to disable
dnstapidentity Server identity string for dnstap messages. Defaults to hostname
dnstapversion Server version string for dnstap messages. Default: “sdns”
dnstaplogqueries Log DNS queries via dnstap. Default: true
dnstaplogresponses Log DNS responses via dnstap. Default: true
dnstapflushinterval Dnstap message flush interval in seconds. Default: 5

Plugin Configuration

SDNS supports custom plugins to extend its functionality. The execution order of plugins and middlewares affects their behavior. Configuration keys must be strings, while values can be any type. Plugins are loaded before the cache middleware in the order specified.

For implementation details, see the example plugin.

Example Configuration

[plugins]
     [plugins.example]
     path = "/path/to/exampleplugin.so"
     config = {key_1 = "value_1", intkey = 2, boolkey = true, keyN = "nnn"}
     [plugins.another]
     path = "/path/to/anotherplugin.so"

Server Configuration Checklist

Features

TODO

Performance

Benchmark Environment

Benchmarking Tool

Benchmark Comparisons

Tests were performed on the following DNS resolvers: SDNS 1.5.0, PowerDNS Recursor 5.0.2, BIND 9.19.12, and Unbound 1.17.1.

Benchmark Results

Resolver Version QPS Avg Latency Lost Queries Runtime Response Codes
SDNS 1.5.0 709/s 137ms 2 (0.004%) 70.5s NOERROR: 79.10%, SERVFAIL: 1.50%, NXDOMAIN: 19.40%
PowerDNS 5.0.2 578/s 156ms 20 (0.04%) 86.5s NOERROR: 67.64%, SERVFAIL: 1.92%, NXDOMAIN: 30.43%
BIND 9.19.12 405/s 200ms 156 (0.31%) 123.0s NOERROR: 67.84%, SERVFAIL: 1.62%, NXDOMAIN: 30.54%
Unbound 1.17.1 338/s 237ms 263 (0.53%) 147.0s NOERROR: 68.20%, SERVFAIL: 1.20%, NXDOMAIN: 30.60%

Performance Summary

SDNS demonstrates superior performance across all key metrics:

Contributing

We welcome pull requests. If you’re considering significant changes, please start a discussion by opening an issue first.

Before submitting patches, please review our CONTRIBUTING guidelines.

:hearts: Made With

Inspired by

License

MIT