Categorygithub.com/semihalev/sdns
repositorypackage
1.6.0
Repository: https://github.com/semihalev/sdns.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# README

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

FlagDescription
-c, --config PATHLocation of the config file. If it doesn't exist, a new one will be generated. Default: /sdns.conf
-v, --versionShow the SDNS version
-h, --helpShow 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.6.0)

KeyDescription
versionConfiguration file version
directoryWorking directory for SDNS data storage. Must be writable by the SDNS process. Default: "/db"
bindDNS server binding address and port. Default: ":53" (0.0.0.0:53 and [::]:53)
bindtlsDNS-over-TLS (DoT) server binding address. Default: ":853"
binddohDNS-over-HTTPS (DoH) server binding address. Default: ":8053"
binddoqDNS-over-QUIC (DoQ) server binding address. Default: ":853"
tlscertificatePath to the TLS certificate file for DoT/DoH/DoQ. Automatically reloaded on changes
tlsprivatekeyPath to the TLS private key file for DoT/DoH/DoQ. Automatically reloaded on changes
outboundipsOutbound IPv4 addresses for DNS queries. Multiple addresses enable random source IP selection per request
outboundip6sOutbound IPv6 addresses for DNS queries. Multiple addresses enable random source IP selection per request
rootserversRoot DNS servers (IPv4). These are the authoritative name servers for the DNS root zone
root6serversRoot DNS servers (IPv6). These are the authoritative name servers for the DNS root zone
dnssecEnable DNSSEC validation for secure DNS responses. Options: "on" or "off". Default: "on"
rootkeysDNSSEC root zone trust anchors in DNSKEY format
fallbackserversUpstream DNS servers used when all others fail. Format: "IP:port" (e.g., "8.8.8.8:53")
forwarderserversForward all queries to these DNS servers. Format: "IP:port" (e.g., "8.8.8.8:53")
apiHTTP API server binding address for statistics and control. Leave empty to disable
bearertokenAPI bearer token for authorization. If set, Authorization header must be included in API requests
blocklistsURLs of remote blocklists to download and use for filtering
blocklistdir[DEPRECATED] Blocklist directory. Now automatically created in the working directory
loglevelLogging verbosity level. Options: crit, error, warn, info, debug. Default: "info"
accesslogPath to the access log file in Common Log Format. Leave empty to disable
nullrouteIPv4 address returned for blocked A queries. Default: "0.0.0.0"
nullroutev6IPv6 address returned for blocked AAAA queries. Default: "::0"
accesslistIP addresses/subnets allowed to make queries. Default allows all: ["0.0.0.0/0", "::0/0"]
querytimeoutMaximum time to wait for any DNS query to complete. Default: "10s"
timeoutNetwork timeout for upstream DNS queries. Default: "2s"
hostsfilePath to hosts file (RFC 952/1123 format) for local resolution. Auto reloads with fs watch. (The directory of the file is being watched, not the file. Best practice is to deploy the file in an individual directory.) Leave empty to disable
expireCache TTL for error responses in seconds. Default: 600
cachesizeMaximum number of cached DNS records. Default: 256000
prefetchPrefetch threshold percentage (10-90). Refreshes popular cache entries before expiration. 0 disables
maxdepthMaximum recursion depth for queries. Prevents infinite loops. Default: 30
ratelimitGlobal query rate limit per second. 0 disables. Default: 0
clientratelimitPer-client rate limit per minute. 0 disables. Default: 0
domainmetricsEnable per-domain query metrics collection. Default: false
domainmetricslimitMaximum number of domains to track in metrics. 0 = unlimited (use with caution). Default: 10000
blocklistManual domain blocklist. Domains listed here will be blocked
whitelistManual domain whitelist. Overrides blocklist matches
cookiesecretDNS cookie secret (RFC 7873) for client verification. Auto-generated if not set
nsidDNS server identifier (RFC 5001) for identifying this instance. Leave empty to disable
chaosEnable responses to version.bind and hostname.bind chaos queries. Default: true
qname_min_levelQNAME minimization level (RFC 7816). 0 disables. Higher values increase privacy but may impact performance
emptyzonesEnable local authoritative responses for RFC 1918 zones. See http://as112.net/ for details
tcpkeepaliveEnable TCP connection pooling for root and TLD servers. Improves performance by reusing connections. Default: false
roottcptimeoutTCP idle timeout for root server connections. Default: "5s"
tldtcptimeoutTCP idle timeout for TLD server connections (com, net, org, etc.). Default: "10s"
tcpmaxconnectionsMaximum number of pooled TCP connections. 0 uses default. Default: 100
dnstapsocketUnix domain socket path for dnstap binary DNS logging. Leave empty to disable
dnstapidentityServer identity string for dnstap messages. Defaults to hostname
dnstapversionServer version string for dnstap messages. Default: "sdns"
dnstaplogqueriesLog DNS queries via dnstap. Default: true
dnstaplogresponsesLog DNS responses via dnstap. Default: true
dnstapflushintervalDnstap message flush interval in seconds. Default: 5

Middleware Configuration

SDNS supports a flexible middleware architecture that allows extending its functionality through built-in middlewares and external plugins.

Built-in Middlewares

Kubernetes DNS Middleware

The Kubernetes middleware provides full DNS integration for Kubernetes clusters, supporting all standard Kubernetes DNS patterns.

Features:

  • Service DNS resolution (A, AAAA, CNAME, SRV)
  • Pod DNS resolution (by IP and hostname)
  • Headless services and StatefulSets
  • ExternalName services
  • Full IPv6 and dual-stack support
  • Real-time Kubernetes API synchronization
  • Optional "killer mode" for extreme performance

Configuration:

[kubernetes]
enabled = true
cluster_domain = "cluster.local"  # Default: cluster.local
killer_mode = false               # Enable for maximum performance
# kubeconfig = "/path/to/kubeconfig"  # Optional, uses in-cluster config by default

Killer Mode Features: When killer_mode is enabled:

  • Zero-allocation wire-format caching
  • Lock-free ML-based query prediction
  • Sharded registry for concurrent operations
  • Predictive cache prefetching
  • 50,000+ QPS on single core

For detailed information, see the Kubernetes middleware documentation.

External Plugins

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"

TLS Certificate Management

SDNS automatically monitors and reloads TLS certificates when they change on disk, making it compatible with automatic certificate renewal systems like Let's Encrypt.

Automatic Certificate Reloading

  • Certificate files are monitored for changes using filesystem notifications
  • When a certificate is updated, SDNS automatically reloads it without dropping connections
  • Works seamlessly with Let's Encrypt and other ACME clients
  • Certificate changes are detected within seconds

Manual Certificate Reload

You can also trigger a certificate reload manually by sending a SIGHUP signal:

$ kill -HUP $(pidof sdns)

This is useful when:

  • Filesystem notifications are not reliable on your system
  • You want to reload certificates on demand
  • You're using a certificate deployment system that doesn't modify files in-place

Certificate Requirements

  • Certificate and key files must be readable by the SDNS process
  • Supports standard PEM-encoded X.509 certificates
  • Works with wildcard certificates
  • Compatible with both RSA and ECDSA certificates

Server Configuration Checklist

  • Increase the file descriptor limit on your server

Features

  • Linux/BSD/Darwin/Windows support
  • Full DNS RFC compatibility
  • DNS queries using both IPv4 and IPv6 authoritative servers
  • High-performance DNS caching with prefetch support
  • Full DNSSEC validation support with RFC 8914 Extended DNS Errors (EDE)
  • DNS over TLS (DoT) support
  • DNS over HTTPS (DoH) support with HTTP/3
  • DNS over QUIC (DoQ) support
  • Multiple outbound IP selection for queries
  • Extensible middleware architecture
  • RTT-based server prioritization with adaptive timeouts
  • Parallel DNS lookups for improved performance
  • Failover to backup servers on failure
  • DNS forwarding support
  • EDNS Cookie support (RFC 7873)
  • EDNS NSID support (RFC 5001)
  • Extended DNS Errors (EDE) support (RFC 8914)
  • Full IPv6 support (both client and server communication)
  • Query-based rate limiting
  • Client IP-based rate limiting
  • IP-based access control lists
  • Comprehensive access logging
  • Prometheus metrics with optional per-domain tracking
  • DNS sinkholing for malicious domains
  • HTTP API for management and statistics
  • Cache purge via API and DNS queries
  • Chaos TXT query support for version.bind and hostname.bind
  • Empty zones support (RFC 1918)
  • External plugin support
  • Binary DNS logging via dnstap protocol (RFC 6742)
  • QNAME minimization for privacy (RFC 7816)
  • Automatic DNSSEC trust anchor updates (RFC 5011)
  • Zero-allocation cache operations for improved performance
  • TCP connection pooling for persistent connections
  • Kubernetes DNS integration with killer mode performance
  • Automatic TLS certificate reloading without downtime

TODO

  • [x] More tests
  • [x] Try lookup NS address better way
  • [x] DNS over TLS support
  • [x] DNS over HTTPS support
  • [x] Full DNSSEC support
  • [x] RTT optimization
  • [x] Access list
  • [x] Periodic priming queries described at RFC 8109
  • [x] Full IPv6 support (server<->server communication)
  • [x] Query name minimization to improve privacy described at RFC 7816
  • [x] DNAME Redirection in the DNS described at RFC 6672
  • [x] Automated Updates DNSSEC Trust Anchors described at RFC 5011
  • [ ] DNS64 DNS Extensions for NAT from IPv6 Clients to IPv4 Servers described at RFC 6147
  • [x] DNS over QUIC support described at RFC 9250
  • [x] Kubernetes DNS integration

Performance

Benchmark Environment

  • Server Specifications:
    • Processor: Apple M1 Pro
    • Memory: 16GB

Benchmarking Tool

  • Tool: DNS-OARC dnsperf
  • Configuration:
    • Query volume: 50,000 sample queries
    • Test date: June 2025

Benchmark Comparisons

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

Benchmark Results

ResolverVersionQPSAvg LatencyLost QueriesRuntimeResponse Codes
SDNS1.5.1712/s136ms2 (0.004%)70.2sNOERROR: 67.82%, SERVFAIL: 1.64%, NXDOMAIN: 30.55%
PowerDNS5.0.2578/s156ms20 (0.04%)86.5sNOERROR: 67.64%, SERVFAIL: 1.92%, NXDOMAIN: 30.43%
BIND9.19.12405/s200ms156 (0.31%)123.0sNOERROR: 67.84%, SERVFAIL: 1.62%, NXDOMAIN: 30.54%
Unbound1.17.1338/s237ms263 (0.53%)147.0sNOERROR: 68.20%, SERVFAIL: 1.20%, NXDOMAIN: 30.60%

Performance Summary

SDNS demonstrates superior performance across all key metrics:

  • Highest throughput: 712 queries per second (23% faster than PowerDNS, 76% faster than BIND, 111% faster than Unbound)
  • Lowest latency: 136ms average (13-43% lower than competitors)
  • Best reliability: Only 2 lost queries out of 50,000 (99.996% success rate)
  • Fastest completion: 70.2 seconds total runtime

With Kubernetes killer mode enabled, SDNS can achieve:

  • 50,000+ QPS on a single core for Kubernetes DNS queries
  • Sub-100μs latency for cached responses
  • Zero allocations in the hot path
  • 90%+ cache hit rates with ML-based prediction

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

  • miekg/dns - Alternative (more granular) approach to a DNS library

Inspired by

License

MIT