Pi-hole 全屋广告过滤实战:NAS 部署一次,全家上网更清净
眼下上网最让人头疼的未必是带宽不够,而是无处不在的广告和追踪探针。网页刚打开,广告位抢先渲染;点开一个 App,后台就冒出一连串数据上报请求;家中的手机、电脑、平板乃至电视盒子,都可能在你不经意间悄悄访问各类统计、跟踪和广告域名。
这次我们就在 NAS 上搭建一个“广告橡皮擦”——Pi-hole,把冲浪体验变得干净利落。
同类方案中,AdGuard Home 和 OxiDNS 也很出色,界面更现代,部署同样便捷,完全可以根据个人偏好选择。

Pi-hole 简介
项目在 GitHub 上的完整名称是 pi-hole/docker-pi-hole,搜索即可找到。
Pi-hole 是一款开源的网络级广告拦截工具,并非浏览器扩展或手机应用,而是一个部署在局域网内的 DNS 过滤服务。只要把终端设备的 DNS 指向 Pi-hole,从理论上说,局域网内所有设备都能享受到过滤效果。
其工作逻辑大致如下:

很多人可能会首先想到:这类 DNS 服务是否最好直接装到路由器里?其实,部署在路由器上并非必需。假如你的路由器性能足够、系统开放且支持 Docker,那么放在路由器里当然顺畅。但现实是,大量家用路由器并不具备这些条件。Pi-hole 的资源消耗很低,在 NAS 上运行后,只需让全屋设备将 DNS 指向这台 NAS 上运行的 Pi-hole,所有设备就都能一道受益。
当然,NAS 需要保持 24 小时开机,以确保服务始终在线。
核心特点
- 一次部署,全家受益:只要在路由器上将 DNS 指向 Pi-hole,局域网内所有设备就会统一通过它解析,无需在每台终端上单独设置。
- 新设备“零”配置:部署完成后,只需在路由器的 DHCP 设置中把 DNS 改为 Pi-hole 的 IP,此后新连上 Wi-Fi 的设备都会自动使用该 DNS。
- 图形化管理面板:自带 Web 管理界面,可直观查看拦截记录、每台设备的请求数量、拦截频率等信息。
- Docker 化部署:官方提供 Docker 镜像,部署灵活、资源开销小。
上手部署
本文以威联通 NAS 为例,采用 Docker Compose 方式进行部署。下面给出完整配置,你可以根据自己的环境适当裁剪:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: pihole-qnap
restart: unless-stopped
ports:
# DNS 服务端口,必须保留
- "53:53/tcp"
- "53:53/udp"
# Pi-hole Web 管理页面
# 不建议直接用 80:80,容易和 NAS 自带服务冲突
- "8081:80/tcp"
# HTTPS 管理页面,可选
# 不需要可以先注释掉
- "8443:443/tcp"
environment:
# 时区
TZ: "Asia/Shanghai"
# Pi-hole 后台登录密码,请务必修改
FTLCONF_webserver_api_password: "请改成你的管理密码"
# Docker bridge 网络下建议设置为 ALL
FTLCONF_dns_listeningMode: "ALL"
# 上游 DNS,可按需调整
# 多个 DNS 用英文分号 ; 分隔
FTLCONF_dns_upstreams: "172.56.1.11;172.56.1.161"
volumes:
# 持久化 Pi-hole 配置
- /share/Container/pihole/etc-pihole:/etc/pihole
cap_add:
# 可选:让 FTL 获得更高调度优先
- SYS_NICE
FTLCONF_dns_upstreams 用于指定 Pi-hole 向上查询的 DNS 服务器。你可以用路由器 WAN 口获取到的 ISP DNS,也可以填入公共 DNS。为了尽量减少解析差异,建议直接使用路由器显示的 DNS 地址,如有多个就用英文分号 ; 隔开。
接着打开威联通的 Container Station,新建一个应用。

实战注意事项
由于 NAS 自带的某些服务已经占用了 53 端口,这里改用 macvlan 方式为 Pi-hole 分配独立 IP。SSH 登录后执行以下命令,创建一个 macvlan 网络(请根据实际局域网修改参数):
docker network create -d macvlan \
--subnet=192.168.100.0/24 \
--gateway=192.168.100.1 \
-o parent=qvs0 \
pihole_macvlan
随后,将 Compose 文件替换为采用该 macvlan 网络的版本:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: pihole-qnap
restart: always
networks:
pihole_macvlan:
ipv4_address: 192.168.100.200 # 给容器一个没被占用的IP
environment:
TZ: "Asia/Shanghai"
FTLCONF_webserver_api_password: "qnap1234"
FTLCONF_dns_listeningMode: "ALL"
FTLCONF_dns_upstreams: "172.56.1.11;172.56.1.161"
volumes:
- /share/Container/pihole/etc-pihole:/etc/pihole
cap_add:
- SYS_NICE
networks:
pihole_macvlan:
external: true
管理后台初探
部署完成后,在浏览器中输入 http://NAS_IP:8081/admin 或 http://pihole的IP/admin 即可打开 Web 管理后台。

登录后映入眼帘的是主仪表盘。和文章开头提到的 AdGuard Home 等方案相比,Pi-hole 的界面确实显得比较复古。

进入后会发现,之前通过环境变量设置的上游 DNS 等信息,在后台的 Settings 页面中也能随时更改。

下方是 Pi-hole 自带的默认广告列表,大约包含三万多个拦截域名。你可以根据实际情况测试效果,也可自行增删规则列表。

点击左侧菜单的「Tools」→「Update Gravity」,执行一次数据库更新,让所有过滤规则生效。

验证与全局配置
在电脑上分别执行以下命令,验证 Pi-hole 的拦截效果:
# 正常网站
nslookup www.baidu.com 192.168.100.200
# 广告域名
nslookup doubleclick.net 192.168.100.200

如果看到广告域名被解析为 0.0.0.0,就代表拦截成功。
确认无误后,进入上级路由器的 DHCP 设置,将 DNS 服务器手动指定为 192.168.100.200,其余参数通常无需修改,然后保存应用。

随后,在电脑终端执行以下命令,检查当前使用的 DNS 服务器:
scutil --dns | grep nameserver

如果返回结果中出现了 Pi-hole 的 IP,就说明全设备 DNS 已统一经过 Pi-hole 解析。
你可以打开一些常去的博客站点测试——许多网站侧边栏里往往会挂着广告。我没有放具体网页截图,但可以向你展示一个小时内的仪表盘统计数据。


尾声
这类方案本质上是在 DNS 层面拦截已知的广告和追踪域名,因此并不能承诺过滤 100% 的广告,特别是 App 内置的信息流广告或平台自有接口投放的广告。不过,部署完成后,网页浏览体验确实大幅提升。
下面简单对比开头提到的另外两个方案,有兴趣的朋友可以自行探索,看看哪款更适合自己的使用场景。

感谢阅读,本次分享就到这里。