
DNS Proxy that is simple and fast with not so simple features. Focused on routed DNS forwarding, filtering and parental control.
A DNS proxy that gives you real control over your home network.
I spent years as a consultant in the "big boy" networking and security "arena". DNS security was/is my daily work, but also a favorite hobby to tinker with. Because I have kids now, and need to be a responsible parent, I took it on myself to filter the big bad internet for them. So I built sdproxy (Simple DNS Proxy). It brings enterprise/big-boy protections/methods/precision to the home network level (kind of).
The proxy is written in Go and compiles to a lean binary for cheap routers. There are NO cloud subscriptions or monthly fees. It speaks every flavor of DNS and includes adaptive admission control to stay stable. It is just lean (kind of), mean, Dutch-engineered precision for the living room. Just you, one executable and a yaml file.
And remember... It's always DNS!
Note: The full_reference_config.yaml is always more up to date than this README. When in doubt, check there.
DNS is the phonebook of the internet - every device on your network looks up a name before it connects anywhere.
sdproxy sits in the middle of that, on your router, and lets you decide what happens next: cache it, block it, route it to a different resolver, apply advanced ML security models, or enforce time limits per child. No cloud subscription, no monthly fee, no external service that goes down.
It's written in Go, compiles to a single binary, and is lean enough to run on cheap home routers (OpenWrt on a TP-Link, GL.iNet or NetGear, pfSense, OPNsense or just a plain Linux box).
See for key advantages vs alternatives here.
Plain old UDP/TCP (port 53), encrypted DNS-over-TLS (DoT), DNS-over-HTTPS (DoH), and DNS-over-QUIC (DoQ).
sdproxy natively parses Alt-Svc headers and seamlessly upgrades standard DoH streams to high-performance HTTP/3 (QUIC) connections on the fly.Protects your browsing from ISP deep-packet inspection by encrypting the TLS Server Name Indication (SNI).
HTTPS/SVCB records, extracts their ECH keys, and secures the TLS handshake completely autonomously.A native, zero-allocation Logistic Regression ML inference engine runs on the hot path. It extracts Shannon entropy, vowel/consonant skew, and n-gram chains to instantly detect and block Algorithmically Generated Domains (DGA) used by botnets, malware, and C2 infrastructure.
Volumetric baseline profiling tracks the Alpha-Smoothed Exponential Moving Average (EMA) of data transferred per-client or per-subnet. It detects sudden, anomalous bursts of data exiting the network over port 53 and blackholes the client in a high-performance Penalty Box.
sdproxy does not just forward queries blindly; it evaluates upstreams dynamically.
Answered something recently? Serve it from cache. sdproxy utilizes 32 cryptographically seeded, lock-free memory shards. If a record expires while still popular, sdproxy triggers a background prefetch so your devices never notice a cache miss. It fully supports RFC 8767 Stale-Serving.
Point it at your DHCP lease files and /etc/hosts and it will answer local name lookups (your NAS, your printer, your Pi) without bothering an upstream resolver. Works with dnsmasq, ISC DHCP, Kea, and odhcpd.
Map a device's identity to a different upstream resolver group or parental profile.
RCODE: REFUSED, NXDOMAIN) directly to a routing rule for instant client quarantine.Set up a profile per child, assign their devices, and configure:
Optional, password-protected browser-based UI for live operations.
Drops any upstream response containing private or bogon IPs (RFC1918, loopbacks, ULAs) returning NXDOMAIN to prevent Server-Side Request Forgery (SSRF) and browser pivoting attacks.
git clone https://github.com/cbuijs/sdproxy
cd sdproxy
go build -o sdproxy .
./sdproxy --config config.yaml
Requires Go 1.25+. No CGo, no external libraries.
server:
listen_udp: ["0.0.0.0:53"]
cache:
enabled: true
size: 1024
upstreams:
default:
- "udp://1.1.1.1:53"
- "udp://9.9.9.9:53"
# OpenWrt MIPS (TP-Link, Netgear, etc.)
GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags="-s -w" -o sdproxy .
# OpenWrt ARM (Linksys, Asus, etc.)
GOOS=linux GOARCH=arm GOARM=7 go build -ldflags="-s -w" -o sdproxy .
# OpenWrt x86_64
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o sdproxy .
The -s -w flags strip debug symbols - saves 30-40% binary size, which matters on small flash storage.
Everything lives in one YAML file. The full_reference_config.yaml in this repo documents every single option inline - that file is the manual. Copy it, strip what you don't need, adjust the rest.
2026/05/01 14:23:01 [DNS] [DoH3+ECH] 192.168.1.42 (alice-iphone) -> google.com A | ROUTE: kids | UPSTREAM: doh3://cloudflare-dns.com | OK
2026/05/01 14:23:02 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> google.com A | ROUTE: kids | CACHE HIT
2026/05/01 14:23:05 [DNS] [DoQ] 192.168.1.10 -> nas.lan A | LOCAL IDENTITY
2026/05/01 14:23:10 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> dga-domain-xzq1.com A | DGA INTERCEPT (Score: 98.2) | NXDOMAIN