razvandimescu/numa
GitHub: razvandimescu/numa
一个用 Rust 从零构建的便携式 DNS 解析器,将广告拦截、本地服务代理、DNSSEC 验证和 ODoH 加密查询集成到单一二进制文件中,让你在任何网络环境下都拥有属于自己的安全 DNS。
Stars: 662 | Forks: 35
# Numa
[](https://github.com/razvandimescu/numa/actions)
[](https://crates.io/crates/numa)
[](LICENSE)
**属于你自己的 DNS。无论你身在何处。** — [numa.rs](https://numa.rs)
单二进制文件中的便携式 DNS 解析器。在任何网络上拦截广告,为你的本地服务命名(`frontend.numa`),通过自动恢复机制覆盖任何主机名,并使用 **ODoH (RFC 9230)** 封装每一个出站查询,确保没有任何单一方能同时看到你的身份和你的请求内容——这一切都在你的笔记本电脑上完成,无需云账户或树莓派。
使用 Rust 从零开始构建。零 DNS 库依赖。开箱即用的缓存、广告拦截和本地服务域名。支持从根域名服务器进行可选的递归解析及完整的 DNSSEC 信任链验证,外加用于加密客户端连接(iOS Private DNS、systemd-resolved 等)的 DNS-over-TLS 监听器。运行 `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 (AUR)
yay -S numa-git
# Windows — 从 GitHub Releases 下载
# 所有平台
cargo install numa
# Docker
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
```
```
sudo numa # run in foreground (port 53 requires root/admin)
```
打开仪表盘:**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 通过注册表在登录时自动启动。
## 本地服务
为你的开发服务命名,而不再需要记忆端口号:
```
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`),通过局域网发现在多台机器间共享服务,或者在 [`numa.toml`](numa.toml) 中配置一切。
## 广告拦截与隐私
通过 [Hagezi Pro](https://github.com/hagezi/dns-blocklists) 拦截 385K+ 个域名。适用于任何网络——咖啡店、酒店、机场。伴随你的笔记本电脑 wherever you go。
三种解析模式:
- **`forward`**(默认)— 透明代理到你现有的系统 DNS。一切如常运转,只是在此基础上增加了缓存和广告拦截。强制门户、VPN、企业 DNS——全部兼容。
- **`recursive`** — 直接从根域名服务器解析。无上游依赖,没有任何单一实体能看到你的完整查询模式。添加 `[dnssec] enabled = true` 即可获得完整的信任链验证。
- **`auto`** — 启动时探测根服务器,如果可达则使用递归解析,如果被屏蔽则回退到加密的 DoH。
DNSSEC 验证完整的信任链:RRSIG 签名、DNSKEY 验证、DS 委派、NSEC/NSEC3 拒绝证明。[了解其工作原理 →](https://numa.rs/blog/posts/dnssec-from-scratch.html)
**DNS-over-TLS 监听器** (RFC 7858) — 接受来自严格客户端(如 iOS Private DNS、systemd-resolved 或 stubby)在 853 端口上的加密查询。提供两种模式:
- **自签名**(默认)— numa 自动生成本地 CA。`numa install` 会将其添加到 macOS、Linux(Debian/Ubuntu、Fedora/RHEL/SUSE、Arch)和 Windows 的系统信任库中。在 iOS 上,通过 `numa setup-phone` 安装 `.mobileconfig` 描述文件。Firefox 使用其独立的 NSS 证书库并忽略系统证书库——如果你需要在 Firefox 中为 `.numa` 服务使用 HTTPS,请手动信任该 CA。
- **自带证书** — 将 `[dot] cert_path` / `key_path` 指向一个受公众信任的证书(例如,通过 DNS-01 挑战获取的 Let's Encrypt 证书,域名指向你的 numa 实例)。客户端无需进行任何信任库设置即可连接——体验与 AdGuard Home 或 Cloudflare `1.1.1.1` 完全一致。
两种模式下均会广播并强制执行 ALPN `"dot"`;拒绝 ALPN 不匹配的握手,以此作为防止跨协议混淆的防御手段。
**手机设置** — 一键将你的 iPhone 或 Android 指向 Numa:
```
numa setup-phone
```
打印出一个二维码。扫描它,安装描述文件,切换证书信任——你手机的 DNS 现在通过 TLS 经过 Numa 进行路由。需要在 `numa.toml` 中配置 `[mobile] enabled = true`。
## 局域网发现
在多台机器上运行 Numa。它们会通过 mDNS 自动发现彼此:
```
Machine A (192.168.1.5) Machine B (192.168.1.20)
┌──────────────────────┐ ┌──────────────────────┐
│ Numa │ mDNS │ Numa │
│ - api (port 8000) │◄───────────►│ - grafana (3000) │
│ - frontend (5173) │ discovery │ │
└──────────────────────┘ └──────────────────────┘
```
从机器 B 执行:`curl http://api.numa` → 代理到机器 A 的 8000 端口。使用 `numa lan on` 启用此功能。
**Hub 模式**:运行一个实例并设置 `bind_addr = "0.0.0.0:53"`,然后将其他设备的 DNS 指向它——它们无需安装任何程序即可获得广告拦截 + `.numa` 解析。
## Docker
```
# 推荐 — 主机网络
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# 端口映射
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/`](packaging/client/) — ODoH 客户端模式(匿名 DNS),Numa + 初始 `numa.toml`。
- [`packaging/relay/`](packaging/relay/) — 公共 ODoH 中继,Numa + Caddy + ACME。
## 功能对比
| | Pi-hole | AdGuard Home | Unbound | Numa |
|---|---|---|---|---|
| 本地服务代理 + 自动 TLS | — | — | — | `.numa` 域名, HTTPS, WebSocket |
| 局域网服务发现 | — | — | — | mDNS,零配置 |
| 开发者覆盖 (REST API) | — | — | — | 自动恢复,可脚本化 |
| 递归解析器 | — | — | 是 | 是,基于 SRTT 选择 |
| DNSSEC 验证 | — | — | 是 | 是 (RSA, ECDSA, Ed25519) |
| 广告拦截 | 是 | 是 | — | 385K+ 域名 |
| Web 管理 UI | 完整 | 完整 | — | 仪表盘 |
| 加密上游 (DoH/DoT) | 需要 cloudflared | 仅 DoH | 仅 DoT | DoH + DoT (`tls://`) |
| 加密客户端 (DoT 监听器) | 需要 stunnel sidecar | 是 | 是 | 原生 (RFC 7858) |
| DoH 服务端点 | — | 是 | — | 是 (RFC 8484) |
| 请求对冲 | — | — | — | 所有协议 (UDP, DoH, DoT) |
| Serve-stale + 预取 | — | — | 在 90% TTL 时预取 | RFC 8767,在 90% TTL 时预取 |
| 条件转发 | — | 是 | 是 | 是(基于后缀的规则) |
| 便携性(笔记本电脑) | 否(设备) | 否(设备) | 服务器 | 单一二进制,macOS/Linux/Windows |
| 社区成熟度 | 5.6 万星,10 年 | 3.3 万星 | 20 年 | 全新 |
## 性能
0.1ms 缓存查询——与 Unbound 和 AdGuard Home 持平。线路级缓存存储原始字节,并支持原位 TTL 修补。请求对冲消除了 p99 延迟峰值:冷递归 p99 为 538ms,而 Unbound 为 748ms(降低 28%),标准差收窄 4 倍。[基准测试 →](benches/)
## 了解更多
- [博客:在 Rust 中从零开始实现 DNS-over-TLS](https://numa.rs/blog/posts/dot-from-scratch.html)
- [博客:在 Rust 中从零开始实现 DNSSEC](https://numa.rs/blog/posts/dnssec-from-scratch.html)
- [博客:我从零开始构建了一个 DNS 解析器](https://numa.rs/blog/posts/dns-from-scratch.html)
- [配置参考](numa.toml) — 所有选项均有内联文档
- [REST API](src/api.rs) — 覆盖、缓存、拦截、服务、诊断的 27 个端点
## 路线图
- [x] DNS 转发、缓存、广告拦截、开发者覆盖
- [x] `.numa` 本地域名 — 自动 TLS、路径路由、WebSocket 代理
- [x] 局域网服务发现 — mDNS,跨机器 DNS + 代理
- [x] DNS-over-HTTPS — 加密上游 + 服务端点 (RFC 8484)
- [x] DNS-over-TLS — 加密客户端监听器 (RFC 7858) + 上游转发 (`tls://`)
- [x] 递归解析 + DNSSEC — 信任链,NSEC/NSEC3
- [x] 基于 SRTT 的域名服务器选择
- [x] 多转发器故障转移 — 带有 SRTT 排序的多上游,回退池
- [x] 请求对冲 — 并行请求挽救丢包和尾部延迟(所有协议)
- [x] Serve-stale + 预取 — RFC 8767,在 <10% TTL 和提供过期数据时进行后台刷新
- [x] 条件转发 — 用于分割水平 DNS 的按后缀规则(Tailscale,VPNs)
- [x] 缓存预热 — 为配置的域主动解析
- [x] 移动设备引导入门 — `setup-phone` 二维码流程、移动端 API、mobileconfig 描述文件
- [ ] pkarr 集成 — 通过 Mainline DHT 实现自治 DNS
- [ ] 全局 `.numa` 域名 — DHT 支持,无需注册商
## 许可证
MIT
标签:AUR, Awesome, crates.io, DNSCrypt, DNS-over-TLS, DNSSEC, DNS枚举, DNS缓存, DNS解析器, Docker, DoT, Homebrew, MacOS, ODoH, RFC 9230, Rust, 加密DNS, 单文件二进制, 去中心化DNS, 可视化界面, 威胁情报, 安全防御评估, 广告拦截, 开发者工具, 本地域名, 本地开发, 本地服务, 系统DNS, 系统管理, 网络安全, 网络安全, 网络安全工具, 网络工具, 网络流量审计, 自主托管DNS, 自定义DNS, 自托管, 请求拦截, 路由配置, 透明代理, 递归解析, 通知系统, 隐私保护, 隐私保护, 零依赖