Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事
Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事
相信大家都遇到过这几个问题
开发时本地起了五六个服务,localhost:3000、localhost:5173、localhost:8080……端口记不住,换台机器更是一片混乱。
出差去咖啡馆用 Wi-Fi,浏览器广告铺天盖地,想开 Pi-hole 但家里的树莓派根本带不走。
调试线上问题时想临时把某个域名指向本地,改 /etc/hosts 还要手动还原,一不小心忘了就出问题。
这三件事,Numa 一个工具全解决了。
Numa 是什么
Numa 是一个用 Rust 从零写成的便携式 DNS 解析器,打包成单个二进制文件(约 8MB),在 macOS、Linux、Windows 上均可运行。不需要树莓派,不需要云账号,不需要注册任何服务。
名字来自古罗马第二任国王 Numa Pompilius——他建立的律法与制度,比王权本身活得更久。

Numa Dashboard 演示
三个核心能力
1. 本地服务域名:告别 localhost:端口号
安装 Numa 后,只需一条 API 调用:
1 | `curl -X POST localhost:5380/services \ |
之后 https://frontend.numa 就能在浏览器里直接打开,有绿色小锁,支持 WebSocket(Vite HMR 不受影响),路径路由也支持:
1 | `app.numa/api → localhost:5001 |
不需要配 mkcert,不需要装 nginx,不需要碰 /etc/hosts。
2. 广告拦截:跟着笔记本走的 Pi-hole
内置 Hagezi Pro 拦截列表,超过 38.5 万个广告和追踪域名。默认开启,零配置。
Pi-hole 和 AdGuard Home 需要部署在树莓派或家庭服务器上,出门就失效。Numa 装在笔记本里,咖啡馆、酒店、机场,到哪都拦截。
3. 开发者 DNS 覆盖:临时改域名,自动还原
调试时想让 api.example.com 临时指向本地:
1 | `curl -X POST localhost:5380/overrides \ |
30 分钟后自动还原。不需要手动改 /etc/hosts,不会忘记还原。
真正的技术亮点:从零实现 DNS 协议
这个项目最值得关注的地方,不是功能列表,而是实现方式。
作者 Razvan Dimescu 没有用任何现成的 DNS 库(没有 hickory-dns,没有 trust-dns,没有 simple-dns)。整个 RFC 1035 DNS 线路协议——报文头、标签压缩、记录类型——全部手写解析。
作者在博客里解释了动机:
“我想真正理解 DNS 是怎么工作的。不是’它把域名翻译成 IP’这种解释——而是线路上的实际字节。DNS 数据包长什么样?标签压缩怎么工作?为什么所有东西都塞进 512 字节?”
一个 DNS 查询包只有 29 个字节:
1 | `Header: AB CD 01 00 00 01 00 00 00 00 00 00 |
这个项目从这 29 个字节开始,一路实现到 DNSSEC 完整信任链验证——RSA、ECDSA P-256、Ed25519 三种签名算法,NSEC/NSEC3 否定证明全部支持。
三种解析模式
1 | `forward(默认)→ 透明代理到系统 DNS,加上缓存和广告拦截 |
LAN 发现:多机器自动互联
在多台机器上运行 Numa,它们通过 mDNS 自动发现彼此:
1 | `机器 A(192.168.1.5) 机器 B(192.168.1.20) |
在机器 B 上执行 curl http://api.numa,请求会自动代理到机器 A 的 8000 端口。一行命令开启:numa lan on。
还可以用 Hub 模式:一台机器运行 Numa 并监听 0.0.0.0:53,其他设备把 DNS 指向它,就能共享广告拦截和 .numa 域名解析,不需要在每台设备上单独安装。
性能数据
这些数字都是可复现的(cargo bench 跑微基准,python3 bench/dns-bench.sh 跑端到端):
指标
数值
缓存命中延迟
691 ns
单线程吞吐量
~200 万 QPS
热路径堆分配
0
ECDSA P-256 DNSSEC 验证
174 ns
与主流解析器对比(dig 测量,相同机器):
解析器
平均延迟
P99
Numa(缓存命中)
<1ms
<1ms
Numa(冷查询)
9ms
18ms
系统解析器
9ms
44ms
Quad9
15ms
43ms
Cloudflare
19ms
132ms
22ms
37ms
冷查询和系统解析器速度相当——瓶颈是上游 RTT,不是 Numa 本身。
与同类工具的对比
Pi-hole
AdGuard Home
Unbound
Numa
本地服务代理 + 自动 TLS
—
—
—
✅ .numa 域名
LAN 服务发现
—
—
—
✅ mDNS 零配置
开发者覆盖 + 自动还原
—
—
—
✅ REST API
递归解析
—
—
✅
✅
DNSSEC 验证
—
—
✅
✅ 完整信任链
广告拦截
✅
✅
—
✅ 38.5万域名
便携性(跟着笔记本走)
❌ 树莓派
❌ 网络设备
❌ 服务器
✅ 单二进制
安装和使用
1 | `# macOS |
1 | `# 前台运行(53 端口需要 root) |
解析管道:每一步都清晰可追踪
Numa 最好的设计决策之一,是把解析过程做成显式的流水线,每一步要么回答,要么传给下一步:
1 | `查询 |
这个结构让扩展变得直接——想加 Tailscale 条件转发?在上游那步之前插入一条规则。想临时覆盖某个域名?加到第一步,带过期时间。
总结点评
这个项目的有意思之处不完全在于功能——广告拦截、本地域名、DNS 覆盖,这几件事单独拿出来都有现成工具可以做到。
Numa 的价值在于把这三件事整合进一个不需要基础设施的工具里,并且整个实现是从 RFC 1035 字节开始手写的。作者在博客里记录了 DNS 线路协议、标签压缩、TTL 懒惰驱逐、DoH 实现的全过程,读下来比很多 DNS 教程都扎实。
目前刚发布不久,代码质量和文档完成度已经相当高。如果你经常在本地跑多个服务、或者在意笔记本出行时的隐私保护,值得试一下。
项目地址:https://github.com/razvandimescu/numa
官网:https://numa.rs
单个二进制,零依赖,DNS 真正属于你自己。
💬 本文评论区已开启,但暂无读者留言。
本文转载自微信公众号,如有侵权请联系删除。
- 标题: Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事
- 作者: lxiol
- 创建于 : 2026-05-06 19:53:55
- 更新于 : 2026-05-12 16:07:03
- 链接: https://blog.lxiol.cn/2026/05/06/Numa用-Rust-从零造一个-DNS-解析器顺手解决了开发者最头疼的几件事/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。