Blocky 0.34 试了三个月:没有 Web UI 才是它的优点

家里的 DNS 上一直跑着某老牌广告拦截——界面漂亮,有图形统计,能按设备分组,看着什么都不缺。但用久了几个事一直让我别扭:它吃内存,一个空载服务常驻 200MB 上下,对一个只做查询转发的进程来说离谱;它的 Web UI 让我每次想看个简单日志都得打开浏览器;更关键的是,我已经在用 Prometheus + Grafana 监控家里的服务了,它的数据完全接不进来。

直到我换上了 Blocky,一切都安静下来了。它没有 Web UI(对,是它的一个卖点),只有一个 YAML 文件、一个二进制、RESTful API 和现成的 Prometheus 端点。换句话说,正合我意。

归到根上,Blocky 做的事情就两件:DNS 转发 + 广告拦截。作者 0xERR0R 一个人维护(Apache-2.0),目前最新是 v0.34.0。GitHub 上 6.9k stars,1,678 次 commit,代码 99.5% 都是 Go。整个项目的目标就一条:让 DNS 拦截足够轻、足够灵活,让 Prometheus / Grafana 这类工具直接读得出来。它可以跑在 OpenWrt 路由器、树莓派、Docker、单进程——随便你选一种。

没有 Web UI 反而是好事

对家庭用户来说,”没有 Web UI”一开始听着像缺点。我用了三年 Pi-hole 和两年某可视化拦截工具,已经习惯打开浏览器看查询日志。但真正用 Blocky 三个月后我意识到,那套图形界面其实没我想象中那么有用——查询频率、命中拦截的域名 TOP 10、最活跃的客户端,这些指标 Prometheus 都能给你,而且能直接进到 Grafana 板子统一管理。

Blocky 在 :4000 端口提供的是 RESTful API(带 Swagger)和 Prometheus 端点(/metrics)。CLI 命令 `./blocky stats` 触发 SIGUSR1 信号后,会直接打印当前命中率、缓存大小、最近一小时的查询数。要禁用拦截 30 分钟跑一次网络测试?`./blocky blocking disable –duration 30m`,一行结束。整套交互是给写脚本的人设计的。

截图里那张 README 一上来把所有支持的协议列得很整齐:UDP/TCP、DoH、DoT、DoQ (RFC 9250)、DoH3 (RFC 9114),DNSSEC 验证默认开。我想要的”加密上游 + 内网缓存 + 全网拦截”它全给,没有任何一个把”再装一个 Unbound”或者”再装一个 cloudflared”这种补丁当成你的事。

配置思路

Blocky 的核心是 config.yml。一份典型的家庭配置大概是这样:

upstream:
  default:
    - 1.1.1.1
    - 8.8.8.8
  conditional:
    - provider: https://dns.quad9.net/dns-query
      match: netflix.com

blocking:
  blackLists:
    ads:
      - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
      - https://big.oisd.nl
  clientGroupsBlock:
    default:
      - ads
    kids:
      - ads
      - parental

clientGroups:
  default:
    blocking: default
  kids:
    upstream:
      - 1.1.1.1
      - https://family-filter.cloudflare-dns.com/dns-query
    blocking: kids

clientLookup:
  192.168.1.100-192.168.1.150: kids
  192.168.1.200: default

ports:
  dns: 53
  http: 4000
  https: 443
  doh: 443

几个值得单拎出来的点:

  • 客户端分组(clientGroups)按 IP 段分配策略。孩子设备的 IP 段映射到 kids 组,使用 family-friendly upstream + 更严的拦截列表;IoT 设备单独一组,给它们一组宽松的规则;剩下的归默认组。这套在 Pi-hole 上能用,但 Blocky 配置起来更扁平。
  • 正则 + CNAME 深检:拦截条目的语法支持正则,还可以深度检查响应的 CNAME 链——比如某个图床域名的 CNAME 指向广告 CDN,Blocky 能拦下来。
  • per-client 速率限制:v0.31 加的新功能,可以给单台设备单独限制 QPS。家里某些 IoT 设备 DNS 风暴(动辄上万次/小时)会拖垮整个解析延迟,用这个就治了。
  • SQLite / dnstap 查询日志:v0.30+ 的 SQLite target 是个好东西,长时间运行的查询日志存在本地一个文件里,要追”为什么这个域名突然不通了”很简单。

部署和两个坑

Docker Compose 是最简单的方式,文档里的配置照搬就行。但是有两个容易踩到的问题我都遇到了:

  1. 端口 53 被占用。如果你的 Linux 发行版开着 systemd-resolved,它会把 53 占着。得先 `systemctl disable –now systemd-resolved`,然后改 /etc/resolv.conf 指到 127.0.0.1。否则 Blocky 启不来。
  2. 配置文件改完不生效。Blocky 通过 SIGHUP 重载,但如果你用 Docker,得在容器内发信号。最偷懒的做法是 `docker exec blocky kill -HUP 1` 或者装一下 官方文档里 SIGHUP reload 那一段提到的 hook。

Prometheus + Grafana 怎么吃数据

这是 Blocky 最香的地方。:4000/metrics 直接暴露:blocky_blocked_totalblocky_cache_sizeblocky_query_totalblocky_response_time_seconds 等等。Grafana 官方 社区 dashboard ID 17477 直接 import 就有,里面有:查询吞吐量、Top 20 客户端、拦截率、缓存命中率、上游 RTT——这些是我以前用 Web UI 费劲看的,现在全在仪表盘里。

我做了一件事是把这段喂到我自己的 NAS 上跑的监控栈里,目前仪表板统一在一个地方。和之前要把 Web UI 单独开一个标签页相比,省了不少事。

它不适合谁

诚实地讲几点限制:

  • 你如果是 DNS 新手,第一次用想看图形界面先学习,那 Blocky 反而劝退。AdGuard Home 的零配置 Web 向导更适合上手。
  • 你不想在家里跑 Prometheus / Grafana 这一整套监控栈,那 Blocky 的”无 UI”特性变成劣势。
  • 你需要在企业级规模跑——每天上千万查询——它的单进程架构不够。需要换 Unbound 或者 PowerDNS 这种。

三个月的感受是,它给我的是一种”设置好就忘了”的服务:200MB 内存释放到 30MB,配置在一个 YAML 文件里能上传到 git,监控数据进了 Grafana,没有 Web UI 让我去碰。这种风格恰好是我想要的——NAS 上不想再多塞一个 GUI 容器。

v0.34.0 当前在持续维护,作者一个人 commit 还是相当勤快的(最近一周还看到动 IPv6 NSID 校验了)。我用了三个月没有想换回去,这就是我现在能给的答案。如果你家里已经有 Prometheus / Grafana、想给 DNS 减减压、又不太依赖 Web UI,Blocky 是个可以认真看一眼的选择。

发表评论