
numa v0.23.0
基于 Rust 的可移植 DNS 解析器 — .numa 本地域名、广告拦截、开发者覆盖
Numa
你的DNS,无处不在。 — numa.rs
一个便携式DNS解析器,单一二进制文件。在任何网络上屏蔽广告,为你的本地服务命名(frontend.numa),使用自动回滚覆盖任意主机名,并通过 ODoH(RFC 9230) 密封每个出站查询,使得没有任何一方能同时看到你的身份和查询内容——这一切都在你的笔记本上完成,无需云账号或树莓派。
完全用Rust从头构建。零DNS库。开箱即用支持缓存、广告拦截和本地服务域名。可选从根域名服务器进行递归解析,并验证完整的DNSSEC信任链,同时提供DNS-over-TLS监听器以支持加密客户端连接(iOS私有DNS、systemd-resolved等)。运行 numa relay 后,同一二进制文件也可成为公共ODoH端点——当前精选的DNSCrypt列表中只有一个可用的中继,因此每个Numa部署都能实质性地扩展生态。单个约8MB的二进制文件,内置一切。

快速开始
# macOS
brew install razvandimescu/tap/numa
# Linux
curl -fsSL https://raw.githubusercontent.com/razvandimescu/numa/main/install.sh | sh
# Arch Linux
pacman -S numa
# Windows — 从GitHub Releases下载
# 所有平台
cargo install numa
# Docker
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# Nix
nix run github:razvandimescu/numa
sudo numa # 前台运行(端口53需要root/管理员权限)
打开仪表盘:**http://numa.numa**(或 http://localhost:5380)
设置为系统DNS:
| 平台 | 安装 | 卸载 |
|---|---|---|
| macOS | sudo numa install | sudo numa uninstall |
| Linux | sudo numa install | sudo numa uninstall |
| Windows | numa install(管理员) + 重启 | numa uninstall(管理员) + 重启 |
在macOS和Linux上,numa以系统服务(launchd/systemd)运行。在Windows上,numa通过注册表在登录时自动启动。Windows还会绑定 127.0.0.2:53(内置的Dnscache占用 127.0.0.1:53)并安装NRPT规则将查询路由到它——因此请针对 127.0.0.2 而非 127.0.0.1 编辑 bind_addr/api_bind_addr。
本地服务
为你的开发服务命名,无需记忆端口号:
curl -X POST localhost:5380/services \
-d '{"name":"frontend","target_port":5173}'
现在 https://frontend.numa 可在浏览器中工作——绿色锁头、有效证书、WebSocket透传支持HMR。无需mkcert、nginx或 /etc/hosts。
添加基于路径的路由(app.numa/api → :5001),通过LAN发现跨机器共享服务,或在 numa.toml 中配置所有内容。
广告拦截与隐私
通过 Hagezi Pro 拦截超过385K个域名。在任何网络上工作——咖啡馆、酒店、机场。随笔记本随身携带。
三种解析模式:
forward(默认)——透明代理到你现有的系统DNS。一切照常工作,只是在之上增加了缓存和广告拦截。尊重强制门户、VPN、企业DNS等。recursive——直接从根域名服务器解析。无上游依赖,没有任何单一实体能看到你的完整查询模式。添加[dnssec] enabled = true以进行完整的信任链验证。auto——启动时探测根服务器,如果可达则递归,如果被阻断则回退到加密的DoH。
DNSSEC验证完整的信任链:RRSIG签名、DNSKEY验证、DS委派、NSEC/NSEC3否定证明。了解其工作原理 →
DNS-over-TLS监听器(RFC 7858)——接受端口853上来自严格客户端(如iOS私有DNS、systemd-resolved或stubby)的加密查询。两种模式:
- 自签名(默认)——numa自动生成本地CA。
numa install将其添加到macOS、Linux(Debian/Ubuntu、Fedora/RHEL/SUSE、Arch)和Windows的系统信任存储中。在iOS上,从numa setup-phone安装.mobileconfig配置文件。Firefox使用自己的NSS存储,忽略系统存储——如果需要对.numa服务使用HTTPS,则在Firefox中手动信任该CA。 - 自带证书——将
[dot] cert_path/key_path指向公开受信任的证书(例如,通过DNS-01挑战从Let's Encrypt获取的指向你numa实例的域名的证书)。客户端连接无需任何信任存储设置——与AdGuard Home或Cloudflare1.1.1.1用户体验相同。
两种模式下都通告并强制执行ALPN "dot";作为跨协议混淆防御,拒绝ALPN不匹配的握手。
手机设置——一步将你的iPhone或Android指向Numa:
numa setup-phone
打印一个二维码。扫描它,安装配置文件,切换证书信任——你的手机DNS现在通过TLS路由到Numa。需要在 numa.toml 中设置 [mobile] enabled = true。
LAN发现
在多台机器上运行Numa。它们通过mDNS自动发现彼此:
机器A (192.168.1.5) 机器B (192.168.1.20)
┌──────────────────────┐ ┌──────────────────────┐
│ Numa │ mDNS │ Numa │
│ - api (端口 8000) │◄───────────►│ - grafana (3000) │
│ - frontend (5173) │ 发现 │ │
└──────────────────────┘ └──────────────────────┘
从机器B:curl http://api.numa → 代理到机器A的8000端口。启用方式:numa lan on。
Hub模式:运行一个实例,设置 bind_addr = "0.0.0.0:53",将其他设备的DNS指向它——它们无需安装任何东西即可获得广告拦截和 .numa 解析。bind_addr 也接受列表,以绑定特定接口子集。
Docker
# 推荐——主机网络(Linux)
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# 端口映射(macOS/Windows Docker Desktop)
docker run -d --name numa -p 53:53/udp -p 53:53/tcp -p 5380:5380 ghcr.io/razvandimescu/numa
仪表盘位于 http://localhost:5380。默认情况下,镜像将API和代理绑定到 0.0.0.0。使用自定义配置覆盖:
docker run -d --name numa --network host \
-v /path/to/numa.toml:/root/.config/numa/numa.toml \
ghcr.io/razvandimescu/numa
多架构:linux/amd64 和 linux/arm64。
即用型Compose食谱:
packaging/client/— ODoH客户端模式(匿名DNS),Numa + 初始numa.toml。packaging/relay/— 公共ODoH中继,Numa + Caddy + ACME。
对比
| Pi-hole | AdGuard Home | Unbound | Numa | |
|---|---|---|---|---|
| 本地服务代理 + 自动TLS | — | — | — | .numa 域名,HTTPS,WebSocket |
| LAN服务发现 | — | — | — | mDNS,零配置 |
| 开发者覆盖(REST API) | — | — | — | 自动回滚,可脚本化 |
| 递归解析器 | — | — | 是 | 是,带SRTT选择 |
| DNSSEC验证 | — | — | 是 | 是(RSA、ECDSA、Ed25519) |
| 广告拦截 | 是 | 是 | — | 385K+ 域名 |
| Web管理界面 | 完整 | 完整 | — | 仪表盘 |
| 加密上游(DoH/DoT) | 需要cloudflared | 仅DoH | 仅DoT | DoH + DoT(tls://) |
| 加密客户端(DoT监听器) | 需要stunnel sidecar | 是 | 是 | 原生(RFC 7858) |
| DoH服务器端点 | — | 是 | — | 是(RFC 8484) |
| 请求对冲 | — | — | — | 所有协议(UDP、DoH、DoT) |
| 提供过期+预取 | — | — | 90% TTL预取 | RFC 8767,90% TTL预取 |
| 条件转发 | — | 是 | 是 | 是(按后缀规则) |
| 便携(笔记本电脑) | 否(设备) | 否(设备) | 服务器 | 单一二进制,macOS/Linux/Windows |
| 社区成熟度 | 56K星,10年 | 33K星 | 20年 | 新 |
性能
缓存查询0.1毫秒——与Unbound和AdGuard Home相当。线级缓存存储原始字节,并原地修补TTL。请求对冲消除p99尖峰:冷递归p99 538毫秒 vs Unbound的748毫秒(−28%),标准差缩小4倍。基准测试 →
了解更多
- 博客:Numa作为你的tailnet解析器
- 博客:用Rust从头实现DNS-over-TLS
- 博客:用Rust从头实现DNSSEC
- 博客:我构建了一个DNS解析器(从头开始)
- 配置参考 — 所有选项内联文档
- REST API — 覆盖、缓存、拦截、服务、诊断
- numa-metrics — 持久化查询历史与分析,设计上脱离主机(不写入SD卡)
路线图
- DNS转发、缓存、广告拦截、开发者覆盖
-
.numa本地域名——自动TLS、路径路由、WebSocket代理 - LAN服务发现——mDNS、跨机器DNS+代理
- DNS-over-HTTPS——加密上游+服务器端点(RFC 8484)
- DNS-over-TLS——加密客户端监听器(RFC 7858)+上游转发(
tls://) - 隐匿DoH——匿名客户端模式+公共同询中继(
numa relay,RFC 9230) - 递归解析+DNSSEC——信任链、NSEC/NSEC3
- 基于SRTT的域名服务器选择
- 多转发器故障切换——多个上游,SRTT排名,回退池
- 请求对冲——并行请求挽救丢包和尾延迟(所有协议)
- 提供过期+预取——RFC 8767,在TTL<10%时后台刷新,并在提供过期时刷新
- 条件转发——按后缀规则用于分裂域DNS(Tailscale、VPN)
- 缓存预热——对配置域名进行主动解析
- 移动端入门——
setup-phone二维码流程、移动API、mobileconfig配置文件 - pkarr集成——通过Mainline DHT实现自主DNS
- 全局
.numa名称——基于DHT,无需注册商
许可证
MIT