Files
mini-dns/README.md
NeoMody 29afb29bc2 Fix bugs, add SOCKS5 proxy, harden error handling
P0 fixes:
- Implement SOCKS5 (RFC 1928) proxy dial with auth support
- Reject UDP upstream + detour (cannot tunnel UDP through proxy)
- Remove dead isProxyDial() and unused Dialer branch

P1 fixes:
- Validate rule group references and hosts IPs at config load
- Default group is now first group (was last)
- TCP handler returns SERVFAIL on resolve error instead of dropping
- Check WriteMsg errors in TCP handler
- Add TLS SNI config to DoH transport
- Graceful shutdown with WaitGroup + 5s drain timeout

Review fixes:
- Check all Write/ReadFull errors in SOCKS5 handshake
- Fix variable shadowing in resolver.go
- Remove redundant fmt.Sprintf and unused import

Add README with config reference and library usage.
2026-04-01 10:02:30 +08:00

3.5 KiB

mini-dns

Lightweight DNS server with split routing, anti-pollution, and speed optimization. Single binary, single dependency (github.com/miekg/dns).

Built for networks where DNS is unreliable: split Chinese/foreign traffic to different upstreams, filter GFW-polluted responses, and pick the fastest IP from CDN results.

Features

  • Split routing -- domain suffix trie, keyword, and exact match rules route queries to upstream groups
  • Multi-protocol -- UDP, TCP, DNS-over-TLS (DoT), DNS-over-HTTPS (DoH)
  • Proxy support -- upstreams can tunnel through HTTP CONNECT or SOCKS5 proxies (detour field)
  • Anti-pollution -- bogon IP filtering, IP blacklist, cross-validation across concurrent upstream responses
  • Speed testing -- TCP connect latency test on A/AAAA results, reorder by fastest
  • Cache -- TTL clamping, prefetch at 10% remaining TTL, serve-stale with background refresh
  • Reverse cache -- IP-to-domain mapping for TUN routing integration
  • Embeddable -- use as a library: NewFromJSON(), Exchange(), Resolve()

Quick Start

go build ./cmd/mini-dns/
./mini-dns -c config.example.json

Test:

dig @127.0.0.1 -p 5353 baidu.com    # routes to CN upstream
dig @127.0.0.1 -p 5353 google.com   # routes to foreign upstream

Configuration

See config.example.json for a complete example.

{
  "listen": "127.0.0.1:5353",
  "upstreams": [
    { "name": "alidns", "addr": "223.5.5.5", "protocol": "udp" },
    { "name": "google-dot", "addr": "8.8.8.8", "protocol": "dot",
      "detour": "http://127.0.0.1:7890" }
  ],
  "groups": [
    { "name": "foreign", "upstreams": ["google-dot"], "strategy": "concurrent" },
    { "name": "cn", "upstreams": ["alidns"], "strategy": "first" }
  ],
  "rules": [
    { "domain_suffix": [".cn"], "group": "cn" },
    { "domain_keyword": ["baidu", "bilibili"], "group": "cn" }
  ]
}

First group is the default for unmatched domains.

Upstream protocols

Protocol Field Notes
udp addr, port (default 53) Cannot use with detour
tcp addr, port (default 53)
dot addr, port (default 853) TLS, supports detour
doh addr, port (default 443), url HTTPS POST, supports detour

Proxy (detour)

"detour": "http://127.0.0.1:7890"       # HTTP CONNECT
"detour": "socks5://user:pass@1.2.3.4"  # SOCKS5

Group strategies

  • concurrent (default) -- query all upstreams, return first success
  • round-robin -- rotate across upstreams
  • first -- try upstreams in order, stop on first success

Cache

{
  "cache": {
    "enabled": true,
    "size": 4096,
    "min_ttl": 60,
    "max_ttl": 86400,
    "prefetch": true,
    "serve_stale": true
  }
}

Pollution filtering

{
  "pollution": {
    "bogon_filter": true,
    "blacklist": ["8.7.198.45"]
  }
}

When enabled, all upstreams in a group are queried concurrently; responses containing bogon or blacklisted IPs are discarded.

Library Usage

server, err := minidns.NewFromJSON(configJSON,
    minidns.WithProtectFunc(protectSocket),  // Android VPN socket protect
)
server.Start()

// Resolve a domain
addrs, _ := server.Resolve("example.com")

// Raw DNS exchange (for TUN integration)
resp, _ := server.Exchange(queryBytes)

// IP -> domain reverse lookup
domain, ok := server.ReverseCache().Lookup(ip)

Cross-compile

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o mini-dns-linux ./cmd/mini-dns/

License

MIT