简单快速的 DNS 代理,具备并不简单的功能。专注于路由 DNS 转发、过滤和家长控制。
一个让你真正掌控家庭网络的 DNS 代理。
我曾在“大厂”网络与安全“竞技场”做过多年顾问。DNS 安全过去是、现在也是我的日常工作,同时也是我最喜欢折腾的爱好。因为我现在有了孩子,需要做一个负责任的家长,所以我主动承担起为他们过滤这个险恶互联网的责任。于是我构建了 sdproxy(Simple DNS Proxy,简单 DNS 代理)。它(某种程度上)把企业级/大厂级的防护、方法和精度带到了家庭网络层面。
该代理使用 Go 编写,可编译为精简的二进制文件,适用于廉价路由器。没有云订阅,也没有月费。它支持各种 DNS 变体,并包含自适应准入控制以保持稳定。它就是为客厅打造的、精简(某种程度上)、强悍、荷兰式工程精度。只有你、一个可执行文件和一个 yaml 文件。
并且记住……永远是 DNS!
注意: 本仓库中的 full_reference_config.yaml 始终比本 README 更新。如有疑问,请查阅该文件。
DNS 是互联网的电话簿——你网络上的每台设备在连接任何地方之前都会先查询一个名称。
sdproxy 位于其中间,运行在你的路由器上,让你决定接下来发生什么:缓存它、阻止它、将其路由到其他解析器、应用高级 ML 安全模型,或对每个孩子强制执行时间限制。没有云订阅,没有月费,没有会宕机的外部服务。
它使用 Go 编写,可编译为单个二进制文件,并且足够精简,可以在廉价家用路由器上运行(TP-Link、GL.iNet 或 NetGear 上的 OpenWrt,pfSense、OPNsense,或者只是一台普通 Linux 机器)。
有关与替代方案相比的关键优势,请参见 KEY_ADVANTAGES.md。
传统的 UDP/TCP(53 端口)、加密的 DNS-over-TLS(DoT)、DNS-over-HTTPS(DoH)以及 DNS-over-QUIC(DoQ)。
sdproxy 原生解析 Alt-Svc 头以及 SVCB/HTTPS ALPN 参数,以即时将标准 DoH 流无缝升级为高性能 HTTP/3(QUIC)连接。通过加密 TLS 服务器名称指示(SNI),保护你的浏览免受 ISP 深度包检测。
_dns.resolver.arpa SVCB/HTTPS)以及 /.well-known/origin-svcb / /.well-known/ech HTTPS 端点,原生向你的本地网络广播自己的密钥。HTTPS/SVCB 记录(以及 L7 .well-known 回退),提取其 ECH 密钥,并完全自主地保护 TLS 握手。一个原生、零分配的 Logistic Regression ML 推理引擎运行在热路径上。它提取香农熵、元音/辅音偏斜、尾随数字模式以及辅音链,以即时检测并阻止僵尸网络、恶意软件和 C2 基础设施使用的算法生成域名(DGA)。
eTLD+1)查询的唯一子域,以拦截慢速低流量 DNS 隧道和信息窃取外泄。sdproxy 不只是盲目转发查询;它会动态评估上游。
max_secure_upstreams(默认 5)个健康服务器。深度检查载荷(CNAME 链、最终 IP 端点),支持 fastest、ordered 和 consolidate(合并应答集)偏好,并在上游不一致或返回被投毒的 NULL-IP 时丢弃或阻止响应。最近回答过什么?从缓存中提供。sdproxy 使用 32 个加密种子内存分片,并可选在重启后保留磁盘持久化。如果某条记录在仍然热门时过期,sdproxy 会触发后台预取,让你的设备永远不会察觉到缓存未命中。它完全支持 RFC 8767 陈旧服务以及 serve_stale_infinite 故障回退。
将其指向你的 DHCP 租约文件和 /etc/hosts,它就会回答本地名称查询(你的 NAS、打印机、树莓派),而无需打扰上游解析器,也不会将 LAN 查询泄露到上游。支持 dnsmasq、ISC DHCP、Kea 和 odhcpd。
将设备身份映射到不同的上游解析器组或家长配置文件。
CC:XX)、客户端名称、TLS SNI(sni:)、HTTP DoH 路径(path:)以及监听端口(port:)。force-and: true 组合多个标识符(例如,子网 AND 监听端口)。rcode: REFUSED、NXDOMAIN、BLOCK、DROP)直接绑定到路由规则,以即时隔离客户端。为每个孩子设置一个配置文件,分配他们的设备,并配置:
group 或按 device)。支持 ALLOW、BLOCK、FREE、LOG、UNLIMITED 以及临时 UNTRIGGER 窗口覆盖。可选的、受密码保护的基于浏览器的 UI(HTTP/HTTPS,或在 DoH 端口 443 上多路复用),用于实时操作。
丢弃任何包含私有或 bogon IP(RFC1918、环回、链路本地、ULA)的上游响应,以防止服务器端请求伪造(SSRF)和浏览器枢轴攻击。
git clone https://github.com/cbuijs/sdproxy
cd sdproxy
go build -o sdproxy .
./sdproxy --config config.yaml
需要 Go 1.26+。无需 CGo。
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 .
-s -w 标志会剥离调试符号——可节省 30-40% 的二进制大小,这在小型闪存存储上很重要。
一切都放在一个 YAML 文件中。本仓库中的 full_reference_config.yaml 内联记录了每一个选项——该文件就是手册。复制它,去掉你不需要的内容,调整其余部分。
2026/05/01 14:23:01 [DNS] [DoH3+ECH] 192.168.1.42 (alice-iphone) -> google.com. A | ROUTE: kids (CLIENT-NAME) | UPSTREAM: [ECH] cloudflare-dns.com (1.1.1.1) (kids) | OK | NOERROR
2026/05/01 14:23:02 [DNS] [UDP] 192.168.1.42 (alice-iphone) -> google.com. A | ROUTE: kids (CLIENT-NAME) | CACHE HIT | NOERROR
2026/05/01 14:23:05 [DNS] [DoQ] 192.168.1.10 -> nas.lan. A | ROUTE: default (DEFAULT) | LOCAL | NOERROR
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