Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事

Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事


相信大家都遇到过这几个问题

开发时本地起了五六个服务,localhost:3000localhost:5173localhost:8080......端口记不住,换台机器更是一片混乱。

出差去咖啡馆用 Wi-Fi,浏览器广告铺天盖地,想开 Pi-hole 但家里的树莓派根本带不走。

调试线上问题时想临时把某个域名指向本地,改 /etc/hosts 还要手动还原,一不小心忘了就出问题。

这三件事,Numa 一个工具全解决了。


Numa 是什么

Numa 是一个用 Rust 从零写成的便携式 DNS 解析器,打包成单个二进制文件(约 8MB),在 macOS、Linux、Windows 上均可运行。不需要树莓派,不需要云账号,不需要注册任何服务。

名字来自古罗马第二任国王 Numa Pompilius------他建立的律法与制度,比王权本身活得更久。


三个核心能力

1. 本地服务域名:告别 localhost:端口号

安装 Numa 后,只需一条 API 调用:

bash 复制代码
curl -X POST localhost:5380/services \
  -d '{"name":"frontend","target_port":5173}'

之后 https://frontend.numa 就能在浏览器里直接打开,有绿色小锁,支持 WebSocket(Vite HMR 不受影响),路径路由也支持:

bash 复制代码
app.numa/api  →  localhost:5001
app.numa/web  →  localhost:3000

不需要配 mkcert,不需要装 nginx,不需要碰 /etc/hosts

2. 广告拦截:跟着笔记本走的 Pi-hole

内置 Hagezi Pro 拦截列表,超过 38.5 万个广告和追踪域名。默认开启,零配置。

Pi-hole 和 AdGuard Home 需要部署在树莓派或家庭服务器上,出门就失效。Numa 装在笔记本里,咖啡馆、酒店、机场,到哪都拦截。

3. 开发者 DNS 覆盖:临时改域名,自动还原

调试时想让 api.example.com 临时指向本地:

bash 复制代码
curl -X POST localhost:5380/overrides \
  -d '{"name":"api.example.com","ip":"127.0.0.1","ttl_minutes":30}'

30 分钟后自动还原。不需要手动改 /etc/hosts,不会忘记还原。


真正的技术亮点:从零实现 DNS 协议

这个项目最值得关注的地方,不是功能列表,而是实现方式

作者 Razvan Dimescu 没有用任何现成的 DNS 库(没有 hickory-dns,没有 trust-dns,没有 simple-dns)。整个 RFC 1035 DNS 线路协议------报文头、标签压缩、记录类型------全部手写解析。

作者在博客里解释了动机:

"我想真正理解 DNS 是怎么工作的。不是'它把域名翻译成 IP'这种解释------而是线路上的实际字节。DNS 数据包长什么样?标签压缩怎么工作?为什么所有东西都塞进 512 字节?"

一个 DNS 查询包只有 29 个字节:

makefile 复制代码
Header: AB CD  01 00  00 01  00 00  00 00  00 00
        ID     Flags  1个问题  0个答案  0个权威  0个附加

Question: 07 65 78 61 6D 70 6C 65  03 63 6F 6D  00  00 01  00 01
              e  x  a  m  p  l  e      c  o  m  结束  A类型  IN类

这个项目从这 29 个字节开始,一路实现到 DNSSEC 完整信任链验证------RSA、ECDSA P-256、Ed25519 三种签名算法,NSEC/NSEC3 否定证明全部支持。


三种解析模式

markdown 复制代码
forward(默认)→ 透明代理到系统 DNS,加上缓存和广告拦截
                  兼容企业 VPN、Tailscale、强制门户

recursive       → 从根域名服务器迭代查询,不依赖任何上游
                  可选开启 DNSSEC 完整信任链验证

auto            → 启动时探测根服务器,能连就用 recursive,
                  被封就自动回退到加密的 DNS-over-HTTPS

LAN 发现:多机器自动互联

在多台机器上运行 Numa,它们通过 mDNS 自动发现彼此:

scss 复制代码
机器 A(192.168.1.5)                  机器 B(192.168.1.20)
┌──────────────────────┐               ┌──────────────────────┐
│ Numa                 │     mDNS      │ Numa                 │
│  - api (port 8000)   │◄─────────────►│  - grafana (3000)    │
│  - frontend (5173)   │   自动发现    │                      │
└──────────────────────┘               └──────────────────────┘

在机器 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
Google 22ms 37ms

冷查询和系统解析器速度相当------瓶颈是上游 RTT,不是 Numa 本身。


与同类工具的对比

Pi-hole AdGuard Home Unbound Numa
本地服务代理 + 自动 TLS --- --- --- .numa 域名
LAN 服务发现 --- --- --- ✅ mDNS 零配置
开发者覆盖 + 自动还原 --- --- --- ✅ REST API
递归解析 --- ---
DNSSEC 验证 --- --- ✅ 完整信任链
广告拦截 --- ✅ 38.5万域名
便携性(跟着笔记本走) ❌ 树莓派 ❌ 网络设备 ❌ 服务器 ✅ 单二进制

安装和使用

bash 复制代码
# macOS
brew install razvandimescu/tap/numa

# Linux
curl -fsSL https://raw.githubusercontent.com/razvandimescu/numa/main/install.sh | sh

# 任意平台(需要 Rust 工具链)
cargo install numa
bash 复制代码
# 前台运行(53 端口需要 root)
sudo numa

# 设置为系统 DNS(macOS / Linux)
sudo numa install

# 打开 Dashboard
open http://localhost:5380
# 或者安装后直接访问 http://numa.numa

解析管道:每一步都清晰可追踪

Numa 最好的设计决策之一,是把解析过程做成显式的流水线,每一步要么回答,要么传给下一步:

复制代码
查询
 → 覆盖规则(有命中?返回,自动计时还原)
 → .numa TLD(是本地服务?反向代理 + 自动 TLS)
 → 拦截列表(命中广告域名?返回 0.0.0.0)
 → 本地 Zone(静态记录?返回)
 → 缓存(有缓存?返回 TTL 调整后的结果)
 → 上游解析(递归 / DoH)
 → DNSSEC 验证
 → 返回客户端

这个结构让扩展变得直接------想加 Tailscale 条件转发?在上游那步之前插入一条规则。想临时覆盖某个域名?加到第一步,带过期时间。


总结点评

这个项目的有意思之处不完全在于功能------广告拦截、本地域名、DNS 覆盖,这几件事单独拿出来都有现成工具可以做到。

Numa 的价值在于把这三件事整合进一个不需要基础设施的工具里,并且整个实现是从 RFC 1035 字节开始手写的。作者在博客里记录了 DNS 线路协议、标签压缩、TTL 懒惰驱逐、DoH 实现的全过程,读下来比很多 DNS 教程都扎实。

目前刚发布不久,代码质量和文档完成度已经相当高。如果你经常在本地跑多个服务、或者在意笔记本出行时的隐私保护,值得试一下。


项目地址github.com/razvandimes...
官网numa.rs

单个二进制,零依赖,DNS 真正属于你自己。

相关推荐
飞哥数智坊1 天前
我为我的龙虾斩分身:OpenClaw 多智能体实操
人工智能·agent
七牛开发者1 天前
HTML is the new Markdown:来自 Claude Code 团队的实践
前端·人工智能·语言模型·html
飞哥数智坊1 天前
在二线城市做AI社群,我的五一节后到底有多疯狂?
人工智能
视***间1 天前
智启边缘,魔盒藏锋——视程空间Pandora系列魔盒,解锁边缘计算普惠新范式
人工智能·区块链·边缘计算·ai算力·视程空间
蛐蛐蛐1 天前
昇腾910B4上安装新版本CANN的正确流程
人工智能·python·昇腾
沪漂阿龙1 天前
AI大模型面试题:线性回归是什么?最小二乘法、平方误差、正规方程、Ridge、Lasso 一文讲透
人工智能·机器学习·线性回归·最小二乘法
Lyon198505281 天前
《文字定律》让AI体验,汉字逻辑与字母逻辑的差异——ChatGPT
人工智能·ai·chatgpt·ai写作
2601_957780841 天前
Claude 4.6 对阵 GPT-5.4:2026 开发者大模型 API 选型深度解析
人工智能·python·gpt·ai·claude
2601_957780841 天前
GPT-5.5 深度解析:2026年4月OpenAI旗舰模型的技术跨越与商业决策指南
大数据·人工智能·python·gpt·openai
zhangfeng11331 天前
利用WorkBuddy 国产小龙虾 制作视频 1 Remotion 方案 2 备选:moviepy 方案渲染视频
人工智能