家里网络总被广告骚扰?这个Go项目帮你搞定

8 次阅读 0 点赞 0 评论 9 分钟原创开源项目

Blocky是一个6389星标的轻量级DNS代理,用Go打造,单二进制部署,支持广告拦截、客户端分组、多种加密协议。本文深入解析其链式架构设计,附带完整的树莓派部署方案。

#DNS #广告拦截 #Go #网络代理 #树莓派 #家庭网络 #轻量级 #微服务
家里网络总被广告骚扰?这个Go项目帮你搞定

作为一名被各类广告弹窗折磨了多年的开发者,我深刻体会到家庭网络管理的痛点:孩子看视频的片头广告、智能电视的推荐弹窗、甚至某些网站的恶意跳转。每次想解决,要么得在每个设备上装插件,要么得买个昂贵的"智能路由器"。

直到我遇到了Blocky——这个6389星标的Go语言项目,给了我一个全新的思路:为什么不直接在网络层面解决问题?

痛点:为什么需要网络级广告拦截

传统广告拦截方案的局限性很明显:

  • 浏览器插件只能管浏览器,管不了电视和手机App
  • 每买新设备都得重新配置
  • 有些设备(比如IoT设备)压根不支持安装插件

而网络级的解决方案,思路就完全不同了:所有设备的域名解析请求都要经过路由器,在这个环节做拦截,一劳永逸。

Blocky做的就是这件事。它是一个轻量级的DNS代理服务器,所有发往互联网的域名查询都会先经过它,它会根据配置的规则决定是否放行。广告域名?直接返回空地址;正常网站?转发给上游DNS服务器。

架构设计:链式解析器的精妙之处

从源码层面看,Blocky的架构设计非常"Go风格"——简洁、模块化、职责单一。它的核心是一个Resolver链,每个DNS请求会依次经过多个处理节点:

复制代码
客户端请求 → CachingResolver → BlockingResolver → ConditionalResolver → UpstreamResolver → 互联网

这种设计让我想起了责任链模式,但实现更加轻量。每个Resolver只关注自己的职责:

  • CachingResolver:检查本地缓存,命中则直接返回
  • BlockingResolver:根据黑名单/白名单决定是否拦截
  • ConditionalResolver:根据域名匹配条件转发到不同上游
  • UpstreamResolver:最终转发到上游DNS服务器

这种链式架构的好处是组合灵活。你可以根据需要启用或禁用某些Resolver,而不会影响整体逻辑。比如在测试环境可以关闭BlockingResolver,在生产环境全部启用。

核心配置:看代码说话

别的项目可能给你一堆复杂的配置文件,Blocky就一个YAML文件搞定。来看看基础配置:

yaml 复制代码
## 上游DNS服务器配置
upstream:
  default:
    - 1.1.1.1                # Cloudflare
    - 8.8.8.8                # Google DNS
    - https://dns.google/dns-query  # DoH加密查询

## 缓存策略
caching:
  minTime: 6h                # 最小缓存时间
  maxTime: 24h               # 最大缓存时间
  prefetching: true          # 启用预取,热门域名提前缓存

## 广告拦截规则
blocking:
  clientGroupsBlock:
    default:                 # 默认组所有设备
      - ads
      - tracking
    kids:                    # 儿童设备组(需配合clientLookup)
      - ads
      - tracking
      - adult                # 额外拦截成人内容

## 拦截列表来源
lists:
  ads:
    - https://someblocklist.com/ads.txt
  tracking:
    - https://someblocklist.com/tracking.txt
  adult:
    - https://someblocklist.com/adult.txt

这段配置有几个值得注意的设计细节:

1. 上游服务器的多样性:你可以同时配置传统的UDP DNS和现代的DoH(DNS over HTTPS)。Blocky会自动随机选择上游服务器,这样既能分散查询请求,又能提升隐私保护——没有单一服务商能完整记录你的查询历史。

2. 缓存预取机制prefetching: true 这个选项很关键。它会监控即将过期的缓存记录,在过期前主动刷新。这意味着你常访问的网站,域名解析几乎是即时的。

3. 客户端分组:可以给不同设备分配不同策略。比如孩子的iPad加入kids组,自动启用成人内容过滤;智能家居设备加入白名单组,避免被误拦截。

实战部署:树莓派上的5分钟安装

我选择在树莓派上部署Blocky,原因很简单:它支持ARM架构,内存占用极低,24小时开机也不心疼电费。

使用Docker方式安装是最简单的:

bash 复制代码
## 创建配置目录
mkdir -p ~/blocky && cd ~/blocky

## 下载配置文件模板
curl -o config.yml https://raw.githubusercontent.com/0xERR0R/blocky/main/config.yml

## 编辑配置文件(根据你的需求修改)
nano config.yml

## 启动Blocky容器
docker run --rm -d \
  --name blocky \
  --restart always \
  -p 53:53/tcp -p 53:53/udp \
  -p 8080:8080 \
  -v ./config.yml:/app/config.yml \
  -v ./data:/app/data \
  spx01/blocky

这里有几个关键点:

  • --restart always:确保树莓派重启后自动恢复服务
  • -p 53:53/tcp -p 53:53/udp:开放标准DNS端口
  • -p 8080:8080:开放管理接口和Prometheus指标端点
  • -v ./data:/app/data:持久化日志和缓存数据容器重启不丢失

启动完成后,登录你的路由器,将全局DNS服务器地址改为树莓派的局域网IP。至此,家里所有设备的查询请求都会经过Blocky处理。

高级玩法:条件转发和查询日志

如果你家里有多个网段,或者想记录所有查询日志,可以用更高级的配置:

yaml 复制代码
## 条件转发:内网域名转发到本地DNS服务器
conditional:
  mapping:
    fritz.box: 192.168.178.1    # 路由器管理的域名
    home.lan: 192.168.1.1       # 自定义局域网

## 客户端识别:通过IP或MAC地址识别设备并分组
clientLookup:
  upstream: 192.168.178.1

## 查询日志:存储到数据库便于分析
queryLog:
  type: mysql
  target: mysql://user:password@tcp(db:3306)/blocky
  logRetention: 7d

## Prometheus监控指标(默认开启)
prometheus:
  enable: true
  path: /metrics

这个配置有几个实用场景:

  1. 内网域名解析:配置fritz.boxhome.lan后,访问内网设备的主机名可以直接解析,无需每台设备配置hosts文件
  2. 设备级策略:通过clientLookup可以自动识别设备类型(基于IP或DHCP分配的固定地址),应用不同策略
  3. 查询日志:记录所有查询请求,可以发现哪些设备在频繁查询广告域名,或者排查某些网站无法访问的原因

避坑指南:这几个地方要注意

部署过程中我遇到了一些问题,分享出来帮助大家少走弯路:

问题1:容器启动后无法解析域名

复制代码
## 检查防火墙规则
sudo iptables -L -n | grep 53

## 树莓派可能需要开启端口转发
sudo sysctl -w net.ipv4.ip_forward=1

问题2:某些网站访问变慢

这通常是因为上游DNS服务器选择不当。建议至少配置两个不同服务商的DNS,比如Cloudflare + Google,必要时还可以添加国内的114DNS或阿里DNS作为备用。

问题3:Smart TV无法联网

某些智能电视会硬编码使用8.8.8.8等公共DNS,绕过路由器设置。解决方法是在路由器上配置强制重定向规则,将所有53端口流量重定向到Blocky。

个人评价:为什么我认为它值得学习

作为一个常年和复杂架构打交道的开发者,Blocky让我看到了简单设计的魅力

1. 功能聚焦:只做一件事——做好轻量级DNS代理。没有强行集成Web管理界面(虽然有第三方项目),没有用户系统,这种克制很难得。

2. 配置即代码:单一配置文件,可以版本控制,修改配置=修改文件。这种理念在容器化时代反而更加合适。

3. 无状态设计:不需要数据库,没有临时文件,单二进制部署。这意味着部署、备份、迁移都极其简单。

当然,它也有不足:对不熟悉命令行的用户不太友好。虽然有完整的API,但不是人人都会用curl。如果能有一个可选的轻量级管理界面,可能会更受欢迎。

总结

用了一周后,家里的广告弹窗明显减少,孩子的iPad也不会跳出奇怪的推荐了。更重要的是,我掌握了家庭网络的"命门"——所有域名的生杀大权都握在自己手里。

如果你符合以下任何一种情况:

  • 有多台设备需要统一管理
  • 想保护孩子上网安全
  • 对隐私有要求
  • 想学习网络编程和DNS协议
  • 需要一个轻量级的网络监控工具

那么Blocky绝对值得一试。这个项目也给了我一个启发:作为开发者,我们不一定非要解决高深的问题,把网络基础服务这种"小事"做到极致,同样能获得大量用户的认可。

6389个star,就是最好的证明。

最后更新:2026-04-01T10:02:52

评论 (0)

发表评论

blog.comments.form.loading
0/500
加载评论中...