现在上网,最烦人的不一定是网速慢,而是各种广告和追踪请求太多。打开网页,广告位先加载;启动 App,后台请求一串接一串;家里的手机、电脑、平板、电视盒子,谁都可能在默默访问各种统计、追踪和广告相关域名。
本期我们就来在NAS上搞个广告橡皮擦 Pi-hole,让上网冲浪清爽一点。
其实类似项目,AdGuard Home、OxiDNS都不错,比较现代化且部署也不难,看大家选择了~

项目介绍
完整项目名:pi-hole/docker-pi-hole,可于GitHub搜索。
Pi-hole 是一个开源的网络级广告拦截项目。它不是浏览器插件,也不是手机 App,而是一个运行在局域网里的 DNS 过滤服务。只要设备的 DNS 指向 Pi-hole,理论上整个局域网里的设备都能受益。
它的工作方式可以理解成这样:

很多人第一反应是:这种 DNS 服务,是不是应该部署在路由器上?
答案是:可以部署在路由器上,但不一定非要。如果你的路由器性能强、系统开放、支持 Docker,那部署在路由器上当然很顺。但现实情况是,很多人的路由器并不适合。Pi-hole 资源占用并不高,NAS部署后,家里设备只需要把DNS指向 NAS 上的 Pi-hole,全屋设备便能一起受益。
不过要注意的是,NAS需要24小时开机在线!
项目特点
一次部署,多设备生效:只要路由器把 DNS 下发给 Pi-hole,局域网里的设备就会统一走 Pi-hole 解析。
不用改每台设备:Pi-hole 部署好以后,只需要在路由器 DHCP 里把 DNS 地址改成 Pi-hole 的 IP,后续新设备连上 Wi-Fi,也会自动使用这个 DNS。
Web 管理后台:有自己的 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 口自动获取到的 DNS,也可以填写常见公共 DNS。为了尽量保持和当前网络环境一致,可以直接使用路由器里显示的 DNS 地址,多个 DNS 之间用英文分号;分隔。
打开Container Station,创建新的应用程序。

相关注意
因为当前NAS所有53端口被占用,而采取了另一种方式。
SSH执行下面代码,为其创建一个网络。这是我所在局域网:
docker network create -d macvlan \
--subnet=192.168.100.0/24 \
--gateway=192.168.100.1 \
-o parent=qvs0 \
pihole_macvlan
然后Docker Compose的代码换成了以下:
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
局内介绍
部署完毕后,输入NAS_IP:8081/admin,或是pihole_IP/admin,即可访问Web界面。

登录后便可看到主面板,那对比我们文章开头提到的两个来说,界面比较复古。

进来后才发现,其实环境变量中我们提前配置的DNS之类,在设置中可以修改。

如下图是项目官方的默认规则,应该有三万多个域名规则~大家根据自己需求进行测试,也可以自行添加规则。

左侧栏的「Tools」-「Update Gravity」,执行一次更新,生成可用的拦截数据库,让规则生效。

配置流程
在PC上,分别输入以下命令,查看返回结果。
# 正常网站
nslookup www.baidu.com 192.168.100.200
# 广告域名
nslookup doubleclick.net 192.168.100.200

可以看到,广告域名被 Pi-hole 拦截,拦截为0.0.0.0。
这一步测试完毕,便可到上级路由,将 LAN/DHCP 设置为192.168.100.200,其他区域一般保持即可,点击保存应用。

接着再PC端输入执行以下命令验证:
scutil --dns | grep nameserver
如下图,这时说明全局 DNS 已经走 Pi-hole 了。

那大家可以打开一些博客站点之类的,站长一般都会两侧栏弄点广告啥的,前后对比下页面便知。
出于某些原因,我这里就不放具体网页截图了,给大家看看一个小时中,仪表盘的数据统计量。


最后
这类项目,本质上解决的是DNS层面的广告/追踪域名过滤。但它们不能保证干掉所有广告,尤其是一些APP、信息流、平台自有接口等广告。
不过搞完之后,确实清爽太多。
关于文章开头提到的另外两个项目的简单对比如下,大家感兴趣可以搜一搜尝试下哪个更适合自己。

感谢观看,本文完。
评论区