Pi-hole是一款开源的网络级广告拦截DNS服务器,最初为树莓派设计,如今已经可以跑在几乎任何Linux设备上,包括NAS、旧笔记本、虚拟机甚至Docker容器。与浏览器广告插件相比,它最大的特点是作用于整个局域网:手机、平板、智能电视、IoT设备只要把DNS指向它,就能在域名解析这一层拦截广告和追踪请求,不需要在每台设备上单独装软件。本文将从原理、安装部署和日常维护三个角度,完整讲解如何搭建和使用Pi-hole。

一、Pi-hole的工作原理:为什么它能在DNS层拦截广告
要理解Pi-hole的价值,得先明白广告是怎么加载的。当你打开一个网页,页面上几乎不可能没有第三方请求:广告联盟脚本、统计埋点、追踪像素,它们都指向特定的域名,比如各种广告平台的双点击域名。浏览器必须先把域名解析成IP地址才能建立连接,而域名解析依赖DNS服务器。Pi-hole正是卡住了这个环节。
Pi-hole本身维护着数百万条广告和追踪域名的屏蔽列表,当客户端发起查询时,它会先判断该域名是否命中列表:命中则直接返回0.0.0.0这样的空地址,客户端拿到空地址后连接失败,广告资源根本无法下载;未命中则将请求转发给上游DNS(如1.1.1.1或8.8.8.8)获取真实结果。整个流程对客户端完全透明,用户感知不到任何区别,只是广告消失了。
这种方式的优点是全局生效、资源开销极小,一台树莓派Zero就能轻松支撑几十台设备。但它也有天然局限:只能按域名拦截,无法过滤与主站共用域名的广告(比如某些视频网站前贴片广告与正片同域),这类场景仍需要浏览器插件配合。所以更合理的做法是Pi-hole打底、插件补充,两者并不冲突。
二、安装部署:用Docker快速搭建Pi-hole
安装Pi-hole最推荐的方式是Docker,隔离性好、升级方便、出问题可以随时销毁重建。假设你已在一台Linux机器上装好Docker,下面这份compose文件可以直接使用:
version: "3"
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp"
environment:
TZ: "Asia/Shanghai"
FTLCONF_webserver_api_password: "你的管理密码"
FTLCONF_dns_upstreams: "223.5.5.5;119.29.29.29"
volumes:
- ./etc-pihole:/etc/pihole
- ./dnsmasq.d:/etc/dnsmasq.d
restart: unless-stopped几个关键点值得说明。53端口是DNS服务端口,必须同时映射tcp和udp;如果宿主机运行了systemd-resolved,它会占用53端口,需要先执行systemctl disable --now systemd-resolved并删除/etc/resolv.conf中的存根地址,否则容器启动会报端口冲突。8080映射的是Web管理界面,部署完成后访问http://服务器IP:8080/admin,输入环境变量中设置的密码即可登录。
上游DNS建议选择延迟较低的公共DNS,国内环境用223.5.5.5(阿里)和119.29.29.29(腾讯)组合比较稳妥,也可以在管理界面的Settings中进一步调整。FTLCONF_dns_upstreams多个值之间用分号分隔。如果你不用Docker,也可以用官方提供的一键脚本curl -sSL https://install.pi-hole.net | bash安装,交互式向导会引导完成全部配置,只是卸载和迁移相对麻烦一些。
部署完成后,最关键的一步是把Pi-hole设置为局域网的DNS服务器。普通做法是在路由器的DHCP设置里把DNS字段改为Pi-hole所在机器的IP,这样所有设备联网时自动获得正确的DNS;如果路由器不支持修改,也可以在需要拦截的设备上手动把DNS指向Pi-hole的IP。无论哪种方式,都建议给Pi-hole主机设置静态IP,避免重启后地址变化导致全网断网。
三、日常维护:黑白名单、分组管理与问题排查
Pi-hole默认订阅的屏蔽列表已经覆盖大量广告域名,但实际使用中难免遇到误杀:某个网站的图片加载不出来、App的登录接口失效,多半是相关域名被拦截了。这时打开管理界面的Query Log查询日志,找到被拦截的域名,确认无害后点击加入白名单即可,通常几秒内生效。反过来,如果发现某个广告域名漏网,也可以手动添加到黑名单。
对于有孩子的家庭,分组管理(Group Management)非常实用。你可以创建一个儿童分组,额外订阅更激进的屏蔽列表,把家里的平板、手机通过MAC地址或IP划入该分组;成人设备则保持默认策略。客户端与分组的绑定支持按设备维度精确控制,这是单纯靠浏览器插件做不到的。
排查问题时,第一步永远是看Query Log。如果发现设备的查询根本没有到达Pi-hole,说明DNS指向不对,或者运营商在路由器上游强制劫持了53端口,此时可以考虑启用Pi-hole的DoH上游配合Cloudflare加密解析绕过劫持。如果查询到了但状态是转发,说明域名没被列表命中,属于正常放行。另外,屏蔽列表需要定期更新,Pi-hole默认通过cron自动执行pihole -g拉取最新列表,Docker部署的容器内已内置该任务,一般无需干预。
最后提醒一点安全事项:Pi-hole的管理界面不要暴露到公网,如果确实需要远程管理,建议通过VPN或反向代理加认证的方式访问。管理界面里能看到全网设备的访问记录,属于敏感信息,保护好它就是保护全家人的上网隐私。