Friday, September 25, 2026

Rethinking home DNS defense with sdproxy

Rethinking home DNS defense with sdproxy

sdproxy is a single-binary Go DNS proxy that brings enterprise-grade filtering, encrypted DNS, and ML-driven DGA detection to home routers and lab networks under your own control.

Toolcbuijs/sdproxy — a lean, single-binary DNS proxy in Go focused on routed DNS forwarding, filtering, and parental control for home networks
CategoryDNS security proxy / network filtering (Go, MIT license)
Primary UseDeploying authorized DNS filtering, encrypted DoT/DoH/DoQ forwarding, DGA detection, and per-device parental controls on routers you own (OpenWrt, pfSense, OPNsense, Linux)
Safe UseRuns exclusively on infrastructure you administer — your own router or lab — for defensive filtering, malware C2 domain blocking, and family/network policy enforcement
Telemetry NoteFully local: sdproxy logs every query with client, route, upstream, and verdict (e.g., DGA INTERCEPT) to local logs and an optional password-protected web panel; no cloud telemetry, no external reporting

Every network engineer eventually mutters "it's always DNS," and sdproxy is what happens when a career DNS security consultant turns that grievance into a household appliance. Written by cbuijs, the project brands itself as Simple DNS Proxy, but the README makes clear the "simple" is doing heavy lifting: this is a dense, policy-driven DNS engine compiled to a single Go binary with zero CGo dependencies, designed to run on cheap home routers. There are no cloud subscriptions, no monthly fees, and no external services that can silently disappear — just one executable and a YAML file. For defenders, the appeal is obvious: it is a full defensive DNS stack you can actually own end to end.

Protocol coverage is the first thing that stands out. sdproxy speaks classic UDP/TCP on port 53 alongside the modern encrypted transports — DoT, DoH, DoQ — and adds what the README calls dynamic DoH3 upgrades: it parses Alt-Svc headers from upstream responses and promotes standard DoH streams to HTTP/3 over QUIC on the fly. On top of that sits full ECH (Encrypted Client Hello) support in both directions. Inbound, the proxy acts as an ECH server and broadcasts its keys on the LAN via DDR (Discovery of Designated Resolvers); outbound, it interrogates upstream HTTPS/SVCB records to extract their ECH keys and encrypt the SNI autonomously. The practical effect is resistance to ISP-level deep-packet inspection of resolver traffic, a genuine enterprise feature compressed into living-room form.

The security engine is where sdproxy departs from typical dnsmasq-grade tooling. A native Logistic Regression ML inference engine runs on the query hot path — the README stresses it is zero-allocation — extracting Shannon entropy, vowel/consonant skew, and n-gram chains to score domains for algorithmic generation. Domains that look like DGA output from botnets or C2 infrastructure are intercepted and answered with NXDOMAIN. The sample log line shows the verdict inline (DGA INTERCEPT (Score: 98.2)), which tells you the scoring is observable rather than a black box — useful when you need to explain a false positive to a family member.

Exfiltration defense is handled through volumetric baseline profiling rather than signature matching. The proxy tracks an alpha-smoothed EMA of data transferred per client and per subnet; sudden anomalous bursts exiting over port 53 — the classic signature of DNS tunneling — trigger a blackhole into what the README calls a high-performance Penalty Box. This is a sensible heuristic for a home context: DNS tunneling is volumetric by nature, and per-client baselining catches the device that suddenly starts shipping kilobytes of garbage where it used to send dozens of bytes.

Upstream handling shows real architectural maturity. Instead of blind forwarding, sdproxy can query all upstreams in a group simultaneously and deep-inspect the payloads — CNAME chains and final IP endpoints — dropping the exchange if any upstream returns mismatched data or a poisoned NULL-IP. Latency-aware selection uses an Epsilon-Greedy bandit over nanosecond EMA timings, sticking to the fastest resolver while reserving roughly 5% of queries for exploration so recovering paths aren't stranded. SingleFlight coalescing merges identical concurrent cache misses into one outbound query, killing Thundering Herd spikes. These are load-balancer-grade techniques, and their presence in a home proxy signals the author's consulting background more than any marketing copy could.

The cache subsystem uses 32 cryptographically seeded, lock-free memory shards, with background prefetch for popular records about to expire and full support for RFC 8767 Stale-Serving — meaning devices can be served slightly stale answers while refreshes happen behind them. Local network awareness is also baked in: point sdproxy at your DHCP lease files or /etc/hosts and it resolves local identities (the NAS, the printer, the Pi) without touching an upstream. The README explicitly lists compatibility with dnsmasq, ISC DHCP, Kea, and odhcpd, which covers essentially the entire home-router ecosystem.

Per-device routing is the feature that makes the whole thing operable. Client identity can be matched via exact MAC, MAC glob masking, IP/CIDR, ASN lookups via IPinfo, client name, TLS SNI, or HTTP DoH paths, and each identity can map to a different upstream group or parental profile. Routing rules can also bind explicit return codes — RCODE: REFUSED or NXDOMAIN — to create instant sinkholes for quarantining a misbehaving client. Parental controls layer on schedules distinguishing school days from weekends, cumulative time budgets with sub-limits (an hour of games, thirty minutes of social), and category blocklists loaded dynamically from public sources like uBlock lists, hosts files, or raw domain lists. Time tracking rides on DNS heartbeat TTLs with disk snapshots so budgets survive reboots — a pragmatic trick that avoids needing an agent on each device.

There is a rebinding defense as well: upstream answers containing RFC1918 space, loopbacks, or ULAs are dropped with NXDOMAIN, closing the SSRF-via-DNS-rebinding pivot that plagues browsers and internal services alike. An optional password-protected web panel exposes live operations — flipping a device group to ALLOW, BLOCK, FREE, or LOG audit mode, streaming query logs, and 24-hour ring-buffer performance charts. The panel being optional matters for router deployments where flash and RAM are scarce.

Operationally, the build story is refreshingly simple: clone the repo and go build -o sdproxy ., requiring only Go 1.25+ and nothing else. Cross-compilation targets are documented for the common router archetypes — GOOS=linux GOARCH=mipsle GOMIPS=softfloat for MIPS OpenWrt boxes, GOARCH=arm GOARM=7 for ARM Linksys/Asus hardware, and plain amd64 for x86 gateways — with -ldflags="-s -w" stripping 30-40% of binary size for constrained flash storage. Configuration lives in a single YAML file, and the README is candid that full_reference_config.yaml in the repo is the real manual, kept more current than the prose.

The minimal config shown in the README is four blocks: a server.listen_udp entry on 0.0.0.0:53, a cache section, and a default upstream group pointing at udp://1.1.1.1:53 and udp://9.9.9.9:53. That is enough to get a working caching forwarder; everything else — ECH, ML, consensus, parental profiles — is opt-in layered on top. For blue-teamers and home-lab operators, sdproxy is best understood as a defensive instrument: it is designed to sit on infrastructure you administer, block malicious domains, and give you per-client observability into DNS behavior. Its logs — client identity, route, upstream, cache state, and ML verdicts — are exactly the telemetry a defender wants, all local, with no phone-home. At 55 stars the project is young, but the engineering density described in the README suggests an author who has spent years doing this professionally and finally built the tool he wanted at home.

Official project repository for cbuijs/sdproxy.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.