Skip to content

esdaniel/sdproxy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

109 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sdproxy

A DNS proxy that gives you real control over your home network.


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, or apply 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 or Netgear, pfSense, OPNsense, or just a plain Linux box).


What it does

Speaks every flavour of DNS

Plain old UDP/TCP (port 53), encrypted DNS-over-TLS (DoT), DNS-over-HTTPS (DoH), DNS-over-QUIC (DoQ), and the HTTP/3 variant. You pick what you want to listen on and what you want to forward to.

Caches aggressively

Answered something recently? Serve it from cache. That means faster browsing and fewer queries leaving your network. If a record expires while it's still popular, sdproxy refreshes it silently in the background so your devices never notice a miss. Stale records are served instantly while the refresh is in flight.

Knows your local network

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 - whatever your router uses.

Routes different devices differently

Map a device's MAC address to a different upstream resolver group. The kid's tablet goes through a filtered resolver, your work laptop goes somewhere else, guests go through a basic default.

You can also route by domain suffix - queries for .lan stay local, queries for your company VPN domains go to your VPN's resolver.

Parental controls - per child, per category

Set up a profile per child, assign their devices by MAC address, and configure:

  • A schedule - internet only between 07:00 and 21:00, for example. Different hours for school days vs weekends.
  • A daily time budget - 2 hours total, with sub-limits per category (1 hour games, 30 minutes social media).
  • Category blocking - social media completely blocked for one child, educational sites always allowed regardless of budget.

Categories (games, streaming, social media, etc.) are loaded from public domain lists. Only the categories you actually use are loaded - if you don't define a budget for "gambling", that list is never touched.

Time is tracked via DNS heartbeat: categorised domains get a short TTL so devices keep checking in. Accuracy is roughly plus or minus 5 minutes per session - more than good enough for home use.

Usage is snapshotted to disk so a router reboot doesn't wipe the day's counters.

Web admin panel

Optional browser-based UI (enable it with a password in the config). No restart needed to flip a group into a different mode:

Mode What it does
DEFAULT Normal - schedule and budget apply as configured.
ALLOW Gate wide open - no schedule, no budget, no blocks. For "I need internet right now" moments.
FREE Suspend the schedule and budget, but keep everything else. Good for supervised homework time.
BLOCK Cut internet entirely for that group.

Override state is intentionally in-memory only - it resets to DEFAULT on restart. These are meant to be quick manual interventions, not permanent changes.

Encrypts and anonymises your DNS traffic

Queries going upstream are stripped of client subnet info (EDNS ECS) and padded to standard sizes so they don't leak which domains you're querying by size alone. Cookies are stripped too.

DDR - clients auto-upgrade to encrypted DNS

With DDR (RFC 9462) enabled, any client that supports it (iOS, Android, modern Windows/macOS) will automatically discover and switch to encrypted DNS. No need to configure each device individually.

Throttles itself under load

Built-in adaptive admission control monitors memory pressure, goroutine counts, and cache miss rate. If the router is getting hammered it backs off gracefully instead of falling over. Zero configuration needed.


Quick start

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.

Minimal config

server:
  listen_udp: ["0.0.0.0:53"]

cache:
  enabled: true
  size: 1024
  min_ttl: 60

upstreams:
  default:
    - "udp://1.1.1.1:53"
    - "udp://9.9.9.9:53"

That's enough to get a caching DNS proxy running. Add sections as you need them.

Build for your router

# 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.


Configuration

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.


Log output

2026/03/16 14:23:01 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> google.com A | ROUTE: kids | UPSTREAM: doh://cloudflare-dns.com | OK
2026/03/16 14:23:02 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> google.com A | ROUTE: kids | CACHE HIT
2026/03/16 14:23:05 [DNS] [UDP] 192.168.1.10 -> nas.lan A | LOCAL IDENTITY
2026/03/16 14:23:10 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> youtube.com A | PARENTAL BLOCK

Disable with logging.log_queries: false. Strip timestamps for systemd/procd with logging.strip_time: true.


Note: The full_reference_config.yaml is always more up to date than this README. When in doubt, check there.

About

DNS Proxy that is simple and fast with not so simple features. Focused on routed DNS forwarding, filtering and parental control.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Go 100.0%