1. 为什么我要折腾树莓派5加OMV7这套组合
家里联网设备一多,广告就跟着泛滥。智能电视开机先来15秒贴片,手机刷个资讯App满屏都是推广位,连家里老人用的平板都时不时弹窗。我一开始是在每台设备上装浏览器插件,但电视端根本装不了,手机端每个App各自为政,维护成本高得离谱。后来试过在路由器上改hosts,结果路由器性能太弱,规则一多就卡,而且改完没法灵活调整。
真正让我下决心动手的,是发现AdGuard Home这个东西。它本质上是一个DNS层面的广告过滤器,工作方式很朴素:所有设备的DNS请求先发给它,它拿着过滤规则比对,命中广告域名的直接返回空结果,正常域名就转发给上游DNS。这样一来,不管你是电视、手机、平板还是电脑,只要DNS指向它,全家设备一次性搞定,不需要每台设备单独装软件。
那为什么选树莓派5而不是旧款或者迷你主机?我自己的考量有三点。第一,树莓派5的CPU是四核Cortex-A76 2.4GHz,内存最高8GB,跑一个DNS过滤服务绰绰有余,实测CPU占用长期在5%以下。第二,它的功耗极低,满载也就5W左右,7×24小时开着一年电费可以忽略。第三,树莓派5终于有了PCIe接口和更快的USB,配合OMV7(OpenMediaVault 7)可以顺便当个轻量NAS用,存点家庭照片、备份文件,一机两用。
OMV7是基于Debian 12的NAS系统,它的好处是把Docker管理、共享文件夹、用户权限这些做成了Web界面,不用天天敲命令行。我在这套系统上跑AdGuard Home,用的是Docker部署方式,原因是隔离性好、升级方便、配置全部集中在compose文件里,哪天树莓派挂了,把配置文件拷到新机器上几分钟就能恢复。
这套方案适合谁?如果你家里有5台以上联网设备,对广告烦不胜烦,又不想每台设备单独折腾,同时手头有一块树莓派或者愿意花几百块买一块,那这套方案非常值得抄。如果你只是想让一台电脑清静,那装个浏览器插件就够了,没必要上这套。下面我把整个部署过程、踩过的坑、参数怎么调,全部摊开讲。
2. 硬件准备与系统安装的完整流程
2.1 树莓派5的硬件清单与选型理由
先说硬件。树莓派5本体我买的是8GB版本,原因很简单:OMV7本身要占一部分内存,Docker容器、AdGuard Home的过滤规则缓存、系统缓存加起来,4GB在规则量大的时候会有点紧张。8GB版本留足余量,后面想加别的服务也不用换机器。
存储方面我用了三样东西:一张32GB的A2级别microSD卡装系统,一块NVMe SSD通过PCIe HAT扩展板做数据盘,还有一个官方27W USB-C电源。这里重点说两个坑。第一,microSD卡一定要买A2级别的,A1级别在OMV7下跑Docker,随机读写会明显拖慢容器启动速度,我一开始用A1卡,AdGuard Home容器启动要20多秒,换A2之后降到5秒以内。第二,电源必须用官方27W或者同等规格的,树莓派5对供电很敏感,我用过一个第三方18W电源,跑起来之后USB设备时不时掉线,换了27W就再没出现过。
散热也不能忽视。树莓派5发热比4代大不少,我加了官方主动散热器,实测满载温度稳定在55度左右,不加散热器会冲到80度以上触发降频。如果你打算7×24小时跑,散热器是必须的。
网络连接我建议用有线。虽然树莓派5支持WiFi,但DNS服务对延迟敏感,有线连接更稳定,而且树莓派5的千兆网口配合OMV7做文件共享也更快。我把它直接插在路由器的LAN口上,路由器里给它分配了一个固定IP,比如192.168.1.10,这样后面配置DNS指向的时候不会因为IP变化而失效。
2.2 OMV7系统烧录与首次启动配置
系统安装这一步,我推荐直接用Raspberry Pi Imager烧录OMV7的镜像。OMV官方提供了针对树莓派的镜像,下载下来之后在Imager里选择“使用自定义镜像”,选中下载的img文件,然后选好SD卡,点写入就行。
写入之前有个关键操作:在Imager的高级设置里,提前配置好WiFi(如果你要用无线)、主机名、用户名密码、SSH开启。我习惯把主机名设成omv.local,用户名用默认的pi,密码设一个强一点的。这样烧录完插卡开机,直接就能SSH连上去,不用接显示器和键盘。
第一次启动会比较慢,因为OMV7要在首次开机时扩展文件系统、初始化配置,大概需要3到5分钟。看到SSH能连上之后,用浏览器访问http://树莓派IP,会进入OMV的Web管理界面。默认用户名是admin,密码是openmediavault,登录后第一件事就是改密码,这个不用多说。
登录进去之后,我建议先做三件事。第一,在“系统”->“更新管理”里检查更新,把系统补丁打全。第二,在“存储”->“磁盘”里确认NVMe SSD被识别到了,如果没识别,检查PCIe HAT是否插紧、是否需要在/boot/firmware/config.txt里加dtparam=pciex1。第三,在“存储”->“文件系统”里把SSD格式化成ext4,然后挂载。挂载点我设成/srv/dev-disk-by-uuid-xxxx,OMV会自动生成这个路径,后面Docker的配置目录就放在这个盘上,避免SD卡频繁写入导致损坏。
提示:OMV7默认会关闭root的SSH登录,所有操作通过
admin用户加sudo执行。如果你习惯直接用root,可以在“系统”->“SSH”里开启“允许root登录”,但我不建议这么做,保持默认更安全。
2.3 安装Docker与Docker Compose环境
OMV7有一个很方便的地方,它自带了一个omv-extras插件源,里面可以直接安装Docker。操作路径是:“系统”->“插件”,搜索openmediavault-compose,勾选安装。这个插件会自动帮你装好Docker Engine和Docker Compose,省去手动配置apt源的麻烦。
装完之后,在OMV左侧菜单会多出一个“服务”->“Compose”的入口。但我不建议直接用OMV的Compose界面来管理AdGuard Home,因为它的配置方式有点绕,不如直接用命令行操作compose文件来得直观。我习惯SSH连上去,在/srv/dev-disk-by-uuid-xxxx/docker/目录下建一个adguard文件夹,所有配置文件都放这里。
先验证Docker是否装好:
docker --version docker compose version如果两条命令都能输出版本号,说明环境没问题。接下来要确认当前用户有权限操作Docker。OMV7安装Docker后会自动创建docker用户组,把admin用户加进去:
sudo usermod -aG docker admin执行完要重新登录SSH才生效。这一步很关键,不然每次跑docker命令都要加sudo,compose文件里的相对路径也容易出问题。
3. AdGuard Home的Docker部署与核心配置
3.1 编写docker-compose文件的关键参数
AdGuard Home的Docker部署,核心就是一个compose文件。我在/srv/dev-disk-by-uuid-xxxx/docker/adguard/下创建docker-compose.yml,内容如下:
version: '3.8' services: adguardhome: image: adguard/adguardhome:latest container_name: adguardhome restart: unless-stopped network_mode: host volumes: - ./work:/opt/adguardhome/work - ./conf:/opt/adguardhome/conf environment: - TZ=Asia/Shanghai这里有几个参数值得展开说。**network_mode: host**是最关键的一步。AdGuard Home需要监听53端口做DNS服务,还需要监听80或3000端口做Web管理。如果用Docker默认的bridge网络,53端口映射出去之后,DNS请求的来源IP会变成Docker网关的IP,导致AdGuard Home的客户端统计功能失效,你没法知道是哪台设备在请求什么域名。用host模式,容器直接共享宿主机的网络栈,来源IP就是真实设备IP,统计才准确。
**restart: unless-stopped**保证树莓派意外重启后容器自动拉起。我试过用always,但有时候手动停掉容器调试,它又自己起来了,unless-stopped更符合我的使用习惯。
卷映射这块,work目录存的是AdGuard Home的运行时数据,包括查询日志、统计数据库;conf目录存的是配置文件AdGuardHome.yaml。这两个目录一定要映射到NVMe SSD上,不要留在容器内部,否则容器一删配置就没了。我见过有人升级镜像时直接docker rm旧容器,结果过滤规则和自定义配置全丢,就是因为没做卷映射。
时区设置成Asia/Shanghai,不然查询日志的时间戳全是UTC,排查问题的时候对不上。
3.2 首次启动与初始化向导
compose文件写好后,在adguard目录下执行:
docker compose up -d第一次启动,AdGuard Home会进入初始化模式,默认监听3000端口做Web配置。这时候用浏览器访问http://树莓派IP:3000,会看到初始化向导。
向导第一步是设置Web管理界面的监听端口。默认是80,但OMV7的Web界面已经占了80端口,所以这里要改成别的,比如8080。我设的是8080,后面访问管理界面就用http://树莓派IP:8080。
第二步是设置DNS服务的监听端口。默认53,这个不用改,因为host模式下53端口是空闲的。但要注意,如果树莓派上装了systemd-resolved或者dnsmasq,53端口会被占用,需要先停掉这些服务:
sudo systemctl stop systemd-resolved sudo systemctl disable systemd-resolvedOMV7默认可能没装这些,但如果你之前手动装过,一定要检查。我踩过一次坑,53端口被dnsmasq占了,AdGuard Home启动后DNS解析全部失败,排查了半天才发现是端口冲突。
第三步是设置用户名密码,这个自己定。设置完之后,AdGuard Home会重启,Web界面从3000端口切到8080端口,DNS服务在53端口开始工作。
3.3 上游DNS的选择与并发查询配置
初始化完成后,进入管理界面,第一件要调的是上游DNS。路径是“设置”->“DNS设置”->“上游DNS服务器”。
AdGuard Home默认给了一堆上游,但很多在国内访问不稳定。我实测下来,比较靠谱的组合是:
223.5.5.5(阿里DNS)119.29.29.29(腾讯DNS)180.76.76.76(百度DNS)
这三个都是国内公共DNS,延迟低、稳定性好。如果你有特殊需求要解析国外域名,可以再加一个1.1.1.1或者8.8.8.8,但要注意这两个在国内的延迟波动比较大,AdGuard Home的并发查询机制会自动选快的,所以加进去也不影响整体速度。
并发查询这个选项一定要开。它的原理是同时向所有上游DNS发请求,谁先返回用谁的。我实测开启后,平均解析延迟从45ms降到18ms。但有个副作用:查询日志里会看到同一个域名有多个上游的响应记录,统计上会显得查询量偏大,这是正常的。
缓存大小我设的是4194304字节(4MB),够存几万条记录。缓存TTL用默认的0,表示尊重域名本身的TTL。如果你发现某些域名解析结果变化频繁,可以把“覆盖最小TTL”设成60秒,强制缓存至少1分钟,减少上游查询压力。
注意:不要同时开“并发查询”和“最快的IP地址”这两个选项。前者是比谁响应快,后者是比谁返回的IP延迟低,两个一起开会导致AdGuard Home对每个请求做两次额外探测,CPU占用会明显上升。我试过同时开,树莓派5的CPU从5%冲到30%,没必要。
4. 过滤规则配置与全家设备接入
4.1 过滤规则的选型与组合策略
AdGuard Home的核心价值在过滤规则。规则本质上是域名黑名单,命中黑名单的域名会被返回0.0.0.0或者NXDOMAIN,广告就加载不出来。
规则不是越多越好。我一开始把网上能找到的规则全加进去,结果规则总数超过50万条,树莓派5的内存占用从200MB冲到1.2GB,而且误杀严重,有些正常网站的功能被拦了。后来我精简成下面这几条,实测覆盖率和性能平衡得最好:
| 规则名称 | 用途 | 规则条数 | 更新频率 |
|---|---|---|---|
| AdGuard DNS filter | 通用广告过滤 | 约5万 | 每日 |
| AdAway Default Blocklist | 移动端广告 | 约3万 | 每周 |
| EasyList China | 中文网站广告 | 约2万 | 每日 |
| CHN: anti-AD | 国内广告专项 | 约8万 | 每日 |
| 自定义规则 | 手动补充 | 按需 | 手动 |
加起来大概18万条,树莓派5跑起来内存占用稳定在400MB左右,CPU几乎无感。anti-AD这条规则特别推荐,它对国内App的广告域名覆盖很全,电视端和手机端的开屏广告基本都能干掉。
添加规则的路径是“过滤器”->“DNS黑名单”,点“添加黑名单”,把规则订阅地址贴进去就行。AdGuard Home会自动定时更新,更新间隔在“设置”->“常规设置”里调,我设的是24小时。
自定义规则这块,我补充了几条针对智能电视的。比如某品牌电视的开机广告域名、某视频App的贴片广告域名,这些通用规则里可能没覆盖,需要自己抓包找。抓包方法后面讲。
4.2 树莓派本机DNS指向与路由器DHCP配置
AdGuard Home跑起来之后,要让全家设备用上它,有两种方式。
第一种是在路由器上改DHCP的DNS设置。登录路由器管理后台,找到DHCP设置,把“主DNS”改成树莓派的IP,比如192.168.1.10,“备用DNS”留空或者也填树莓派IP。这样所有通过DHCP获取IP的设备,DNS都会自动指向AdGuard Home。这是最省事的方式,新设备连上WiFi就自动生效。
但有些路由器不允许改DHCP下发的DNS,或者你不想动路由器配置,那就用第二种方式:在每台设备上手动改DNS。电视在“网络设置”里把DNS改成手动,填树莓派IP;手机在WiFi高级设置里改。这种方式麻烦一点,但胜在可控。
树莓派本机也要把DNS指向自己。OMV7默认用/etc/resolv.conf,但这个文件可能被systemd-resolved或者NetworkManager管理。我直接在OMV的Web界面里改:“网络”->“接口”->选中网卡->“编辑”->“高级设置”->“DNS服务器”,填127.0.0.1。这样树莓派自己的DNS请求也走AdGuard Home,方便测试。
改完之后验证一下:
nslookup doubleclick.net 127.0.0.1如果返回0.0.0.0或者NXDOMAIN,说明过滤生效了。再试一个正常域名:
nslookup baidu.com 127.0.0.1能正常返回IP,说明上游转发也没问题。
4.3 电视端与手机端的接入验证
电视端接入后,最直观的变化是开机广告没了。我家的电视之前开机要等15秒广告,DNS指向AdGuard Home之后,开机直接进桌面。但要注意,有些电视的广告是IP直连的,不走DNS,这种AdGuard Home拦不住。我实测下来,大概70%的电视广告走DNS,剩下30%需要配合路由器防火墙规则或者hosts屏蔽,那是另一个话题了。
手机端的变化更明显。刷资讯App的时候,信息流里的推广卡片会变成空白,App启动时的开屏广告直接跳过。但有个副作用:某些App会检测DNS被拦截,然后弹窗提示“网络异常”。遇到这种情况,在AdGuard Home的“查询日志”里找到被拦截的域名,把它加到“自定义规则”的白名单里,格式是@@||域名^,这样该域名就不被拦截了。
验证手机是否生效,最简单的办法是在手机浏览器访问http://树莓派IP:8080,能打开AdGuard Home管理界面说明网络通了。然后在“查询日志”里看有没有手机的IP在请求,有的话就说明DNS已经指向过来了。
5. 实际运行中的问题排查与性能调优
5.1 常见问题速查表
这套系统我跑了小半年,遇到过不少问题,整理成表格方便对照排查:
| 现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 所有设备无法上网 | AdGuard Home容器挂了 | docker ps看容器状态 | docker compose restart |
| 部分网站打不开 | 规则误杀 | 查询日志看被拦域名 | 加白名单`@@ |
| DNS解析慢 | 上游DNS不稳定 | 看查询日志的响应时间 | 换上游或开并发查询 |
| 电视广告还在 | 广告走IP直连 | 抓包看请求目标 | 需路由器层拦截 |
| 管理界面打不开 | 8080端口冲突 | `ss -tlnp | grep 8080` |
| 树莓派温度过高 | 散热不足 | vcgencmd measure_temp | 加散热器或降频 |
| 查询日志不记录 | 日志级别设置 | 设置->常规->查询日志 | 开启并设保留天数 |
| 容器启动失败 | 配置文件损坏 | docker logs adguardhome | 从备份恢复conf目录 |
5.2 查询日志分析与误杀处理
AdGuard Home的查询日志是排查问题的核心工具。在“查询日志”页面,你能看到每一条DNS请求的时间、客户端IP、请求域名、处理结果(放行/拦截/缓存)。
我遇到最多的问题是误杀。比如某次更新规则后,家里老人说微信打不开图片了。我在查询日志里筛选“已拦截”,发现mmbiz.qpic.cn被拦了,这是微信公众号图片的域名,被某条规则误判成广告。处理方法是在“自定义过滤规则”里加一条:
@@||mmbiz.qpic.cn^@@表示白名单,||表示域名匹配,^表示分隔符。加完之后刷新,图片就正常了。
还有一种情况是漏杀。电视开机广告还在,但查询日志里看不到相关请求。这说明广告不走DNS,可能是IP直连或者走了DoH(DNS over HTTPS)。DoH是加密的DNS请求,AdGuard Home默认拦不住。解决办法是在路由器上屏蔽已知的DoH服务器IP,或者用AdGuard Home的“DNS重写”功能,把DoH域名解析到0.0.0.0。但道高一尺魔高一丈,有些App内置了DoH服务器IP,只能靠抓包找出来再封。
5.3 性能调优与资源占用控制
树莓派5跑AdGuard Home,默认配置下资源占用很低,但规则量大了之后需要调优。我做了这几件事:
第一,限制查询日志保留天数。默认AdGuard Home会保留所有查询日志,时间长了数据库会膨胀到几百MB。我在“设置”->“常规设置”里把“查询日志保留”设成7天,“统计保留”设成30天。这样既能回溯近期问题,又不会占太多空间。
第二,调整缓存大小。前面说过设4MB,实测够用。如果你家里设备特别多(20台以上),可以调到8MB。但不要超过16MB,树莓派5的内存虽然够,但AdGuard Home的缓存管理是单线程的,太大反而拖慢查询速度。
第三,关闭不必要的功能。AdGuard Home自带“安全搜索”“家长控制”这些功能,如果你不用,就在设置里关掉。我试过开着“安全搜索”,结果某些正常搜索被强制跳转到安全搜索页面,体验很差。
第四,监控容器资源。用docker stats可以实时看容器的CPU和内存占用。我正常运行时CPU在2%到5%之间波动,内存稳定在400MB左右。如果发现CPU持续超过20%,大概率是规则太多或者开了并发查询加最快IP,需要精简规则。
docker stats adguardhome --no-stream这条命令输出一次快照,方便脚本定时采集。
5.4 备份与迁移的实操经验
这套系统最怕的是SD卡挂掉。我做过一次迁移测试,把整个AdGuard Home从一张卡迁到另一张卡,流程如下:
第一步,在旧机器上停掉容器:
cd /srv/dev-disk-by-uuid-xxxx/docker/adguard docker compose down第二步,打包配置目录:
tar -czvf adguard-backup.tar.gz work conf docker-compose.yml第三步,把压缩包拷到新机器,解压到相同路径,然后docker compose up -d。整个过程不到5分钟,所有过滤规则、自定义配置、查询统计全部保留。
我建议每周自动备份一次。在OMV的“系统”->“计划任务”里加一条,每周日凌晨3点执行打包命令,备份文件存到NVMe SSD的另一个目录。这样即使SD卡挂了,配置还在。
提示:不要把备份存在SD卡上。SD卡挂了备份也跟着没,等于没备份。一定要存到NVMe SSD或者外部存储。
6. 这套方案还能怎么扩展
AdGuard Home跑稳之后,我顺手在OMV7上加了几个服务。一个是Unbound,做本地递归DNS,这样上游DNS被污染的时候还能自己解析。另一个是Nginx Proxy Manager,给AdGuard Home的管理界面加个域名和HTTPS,不用记IP和端口。还有一个是Home Assistant,把AdGuard Home的统计接进去,在家庭面板上看拦截了多少广告。
树莓派5的性能跑这些绰绰有余。我实测同时跑AdGuard Home、Unbound、Nginx Proxy Manager、Home Assistant四个容器,CPU占用峰值也就40%,内存用了2.5GB,8GB版本完全扛得住。
如果你只想安安静静去广告,那AdGuard Home一个就够了,不用折腾这么多。但如果你像我一样喜欢把树莓派当家庭服务器用,这套OMV7加Docker的组合非常灵活,想加什么服务都是改个compose文件的事。
最后分享一个我踩过的坑:不要用OMV的Web界面直接改Docker容器的配置。OMV的Compose插件有自己的配置数据库,你在命令行改的compose文件,它不认;你在它界面里改的,又和命令行文件不同步。我建议要么全用命令行,要么全用OMV界面,别混着来。我混着用的时候,有一次OMV重启后自动用旧配置覆盖了我的compose文件,AdGuard Home的host网络模式被改回bridge,所有客户端统计全乱了。后来我干脆把OMV的Compose插件禁用,纯命令行管理,再没出过问题。