2026年11月

飞牛 OS + Docker + Pi-hole 家庭双栈 DNS 部署说明

作者: Chatgpt, Leo
文档用途: 部署记录、后续维护、重装及故障恢复\
部署平台: 飞牛 OS(NAS)\
DNS 服务: Pi-hole(Docker)\
网络模式: IPv4 + IPv6 双 Macvlan\
更新时间: 2026-11-01


1. 部署目标

在家庭网络中部署 Pi-hole,由它统一承担 DNS 解析和广告域名过滤。

主要目标:

  • 家庭设备统一使用 Pi-hole DNS。
  • 同时支持 IPv4 和 IPv6,避免设备通过 IPv6 DNS 绕过过滤。
  • 过滤抖音、快手、微信视频号等应用的部分广告及追踪域名。
  • 使用中文 DNS 过滤清单增强广告过滤效果。
  • 保留家庭网络正常上网能力,不改变现有路由器拨号和 DHCP 架构。

注意: Pi-hole 是 DNS 层过滤器,不能直接隐藏网页中的广告元素,也不能保证去除 X 信息流推广帖子。DoH、DoT、VPN 和应用内置 DNS 仍可能绕过 Pi-hole。

2. 家庭网络拓扑

运营商网络
    │
烽火光猫(桥接模式)
    │
    │ PPPoE
    ▼
TP-Link 路由器(负责拨号)
    │
    │ LAN:192.168.31.0/24
    │
    ├── Windows:192.168.31.41
    │
    ├── Pi-hole:192.168.31.53
    │             IPv6:240e:3a6:1e18:a160::1000
    │
    └── NAS:192.168.31.100

2.1 网络参数

项目配置
NAS 网卡enp1s0
NAS IPv4192.168.31.100
LAN 网段192.168.31.0/24
IPv4 网关192.168.31.1
Pi-hole IPv4192.168.31.53
当前 IPv6 前缀240e:3a6:1e18:a160::/64
Pi-hole IPv6240e:3a6:1e18:a160::1000
IPv6 网关240e:3a6:1e18:a160:9e47:82ff:fe88:2809
Docker IPv4 网络pihole_macvlan
Docker IPv6 网络pihole_ipv6

IPv6 前缀由运营商分配,可能随 PPPoE 重新拨号而变化。上述 IPv6 地址不能视为永久不变。

3. Docker 部署

3.1 目录结构

Compose 文件:

/vol1/1000/Docker/pihole/compose.yaml

数据目录:

/vol1/1000/Docker/pihole/etc-pihole

管理页面:

http://192.168.31.53/admin

容器名称:

pihole

3.2 Docker 版本

部署时环境:

组件版本
Docker28.5.2
Docker Composev2.40.3
Pi-hole 镜像pihole/pihole:latest

3.3 IPv4 Macvlan 网络

原有 IPv4 Docker 网络:

pihole_macvlan

配置为外部网络,Compose 不负责创建或管理它。

检查网络:

docker network inspect pihole_macvlan

应确认网络驱动为 macvlan,Parent interface 为 enp1s0,IPv4 地址池和网关与家庭 LAN 一致。

3.4 创建 IPv6 Macvlan 网络

执行:

docker network create \
  --driver macvlan \
  --ipv4=false \
  --ipv6 \
  --subnet=240e:3a6:1e18:a160::/64 \
  --gateway=240e:3a6:1e18:a160:9e47:82ff:fe88:2809 \
  --opt parent=enp1s0 \
  pihole_ipv6

说明:

  • --ipv4=false:该网络只负责 IPv6。
  • --ipv6:启用 IPv6。
  • --subnet:当前家庭 LAN 的 IPv6 前缀。
  • --gateway:TP-Link 路由器在该网段的 IPv6 地址。
  • --opt parent=enp1s0:使用 NAS 实际连接家庭 LAN 的物理网卡。

检查:

docker network inspect pihole_ipv6

重点确认:

EnableIPv4: false
EnableIPv6: true
Subnet: 240e:3a6:1e18:a160::/64
Gateway: 240e:3a6:1e18:a160:9e47:82ff:fe88:2809
Parent: enp1s0

注意:如果网络已经创建,不要重复执行创建命令。修改已有网络的网段或网关通常需要重新创建网络,可能影响容器连接。

3.5 Compose 配置文件

当前使用的 compose.yaml:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    hostname: pihole

    networks:
      pihole_macvlan:
        ipv4_address: 192.168.31.53
      pihole_ipv6:
        ipv6_address: "240e:3a6:1e18:a160::1000"

    environment:
      TZ: Asia/Shanghai
      FTLCONF_webserver_api_password: "替换为自己的管理密码"
      FTLCONF_dns_upstreams: "223.5.5.5;119.29.29.119"

    volumes:
      - /vol1/1000/Docker/pihole/etc-pihole:/etc/pihole

    restart: unless-stopped

networks:
  pihole_macvlan:
    external: true
    name: pihole_macvlan

  pihole_ipv6:
    external: true
    name: pihole_ipv6

配置说明:

  • IPv4 和 IPv6 使用两个独立的 Macvlan 网络。
  • IPv4 固定地址为 192.168.31.53。
  • IPv6 固定地址为 240e:3a6:1e18:a160::1000。
  • Pi-hole 配置数据通过目录挂载保存。
  • FTLCONF_dns_upstreams 指定上游 DNS。
  • restart: unless-stopped 使容器在 Docker 服务重启后自动恢复。

注意:上面的 Compose 示例中上游 DNS 应使用已经实际验证的地址。当前部署原始配置为:

223.5.5.5
119.29.29.119

请以原配置为准,不要因为示例中的其他地址而擅自更改。

密码安全: 管理密码不要公开粘贴到日志或交流内容中。此前曾在排查过程中暴露过一次明文密码,建议更换为新的强密码。

3.6 Compose 配置检查

进入目录:

cd /vol1/1000/Docker/pihole

检查 YAML 配置:

docker compose config -q

没有输出且返回成功,表示 Compose 配置语法通过。

查看容器:

docker compose ps

查看容器网络:

docker inspect pihole \
  --format '{{json .NetworkSettings.Networks}}'

应同时看到:

  • pihole_macvlan:IPv4 192.168.31.53
  • pihole_ipv6:IPv6 240e:3a6:1e18:a160::1000

3.7 当前容器的 IPv6 接入记录

首次配置过程中,曾通过以下命令将正在运行的容器接入 IPv6 网络:

docker network connect \
  --ip6 240e:3a6:1e18:a160::1000 \
  pihole_ipv6 \
  pihole

这是本次部署过程中使用的临时接入操作。现在 Compose 文件已经声明了两个网络,后续应由 Compose 管理容器网络配置。

应用 Compose 时使用过:

docker compose up -d --no-recreate

随后检查:

docker inspect pihole \
  --format '{{.State.Status}} {{.State.Health.Status}}'

实际结果:

running healthy

重要: --no-recreate 不会重建现有容器,因此它只能证明当前容器没有因 Compose 操作而中断,不能证明删除并重建容器后 IPv6 网络一定会自动恢复。

当前双栈运行正常,重建后的持久性尚未实测。不要为了验证而随意执行 docker compose down 或 docker compose up -d --force-recreate,否则会造成 DNS 服务短暂中断。

4. TP-Link 路由器 DNS 配置

Pi-hole 不承担 DHCP 服务,继续由 TP-Link 路由器负责 DHCP。

4.1 DHCPv4

设置:

项目配置
DHCP 服务开启
首选 DNS192.168.31.53
备用 DNS留空

不要设置公共 DNS 作为备用 DNS,否则部分客户端可能直接使用备用 DNS,绕过 Pi-hole。

4.2 DHCPv6

设置:

项目配置
DHCPv6 服务开启
首选 DNS240e:3a6:1e18:a160::1000
备用 DNS留空
IPv6 地址池240e:3a6:1e18:a160:: 至 ...::ff
地址租期120 分钟

Option16、Option52 等其他选项没有为了本次部署而修改。

注意:不要仅凭 Option52 的显示值推断它就是 DNS 服务器地址。DHCPv6 的 DNS 服务器标准选项是 Option 23。

5. Windows 客户端验证

以 Windows 11 为例。

5.1 查看 DNS 配置

PowerShell:

Get-DnsClientServerAddress -InterfaceAlias "Ethernet"

预期:

IPv4: 192.168.31.53
IPv6: 240e:3a6:1e18:a160::1000

如果 IPv6 还出现其他 DNS 地址,应进一步确认来源,不要直接假定它一定能够绕过或一定不能绕过 Pi-hole。

5.2 测试正常域名解析

Resolve-DnsName www.baidu.com -Type A

预期返回正常的公网 IPv4 地址。

5.3 测试抖音拦截

Resolve-DnsName www.douyin.com -Type A

预期:

0.0.0.0

5.4 查看 Pi-hole Query Log

进入:

http://192.168.31.53/admin

查看 Query Log。

本次实际验证结果:

  • 百度域名请求到达 Pi-hole,并正常解析。
  • 请求来源包含 Windows 客户端的 IPv6 地址。
  • www.douyin.com 命中 regex 规则。
  • Pi-hole 返回 0.0.0.0。

这证明 Windows 的上述 DNS 测试确实经过 Pi-hole,而不是仅仅显示了 DNS 配置地址。

6. Pi-hole 广告过滤清单

6.1 基础清单

保留 Pi-hole 默认的 StevenBlack 清单。

6.2 添加中文 DNS 清单

建议使用适用于 DNS 层的规则文件,而不是浏览器专用规则。

① anti-AD

项目:privacy-protection-tools/anti-AD

Pi-hole 专用域名清单:

https://gcore.jsdelivr.net/gh/privacy-protection-tools/anti-AD@master/anti-ad-domains.txt

其他 CDN:

https://cdn.jsdelivr.net/gh/privacy-protection-tools/anti-AD@master/anti-ad-domains.txt

https://testingcf.jsdelivr.net/gh/privacy-protection-tools/anti-AD@master/anti-ad-domains.txt

https://fastly.jsdelivr.net/gh/privacy-protection-tools/anti-AD@master/anti-ad-domains.txt

项目主页:

https://github.com/privacy-protection-tools/anti-AD

② AdRules DNS

项目:Cats-Team/AdRules

DNS 规则:

https://gcore.jsdelivr.net/gh/Cats-Team/AdRules@main/dns.txt

其他 CDN:

https://cdn.jsdelivr.net/gh/Cats-Team/AdRules@main/dns.txt

https://testingcf.jsdelivr.net/gh/Cats-Team/AdRules@main/dns.txt

https://fastly.jsdelivr.net/gh/Cats-Team/AdRules@main/dns.txt

项目主页:

https://github.com/Cats-Team/AdRules

注意:

  • dns.txt 是 DNS 专用规则,不要误选 adblock.txt。
  • CDN 缓存可能导致更新略有延迟。
  • 订阅地址如果将来失效,应先检查项目主页的文件路径和分支。
  • 不要把多个 CDN 镜像地址同时添加为多个清单,否则相同规则会被重复下载。

6.3 添加清单的操作

在 Pi-hole 管理页面:

  1. 进入 Lists(或 Settings → Lists,具体取决于版本)。
  2. 添加订阅 URL。
  3. 保存清单。
  4. 进入 Gravity 更新页面:
http://192.168.31.53/admin/gravity
  1. 点击 Update 或 Update Gravity。
  2. 等待下载、解析及数据库更新完成。

重要:添加 URL 不等于下载清单。

Pi-hole 的流程是:

添加订阅地址
      │
      ▼
保存 URL
      │
      ▼
更新 Gravity
      │
      ▼
下载清单
      │
      ▼
解析域名、去重
      │
      ▼
生成实际生效的拦截数据库

也可以在 NAS 终端手动执行:

docker exec -it pihole pihole -g

查看容器日志:

docker logs --tail 100 pihole

如果清单下载失败,应检查 URL、CDN 可访问性和 Gravity 输出,不要反复添加相同地址。

7. 自定义广告过滤规则

对于抖音、快手等应用,可以在 Pi-hole 中增加自定义正则规则。

当前候选规则:

(^|\.)douyin\.com$
(^|\.)iesdouyin\.com$
(^|\.)douyinvod\.com$
(^|\.)douyincdn\.com$
(^|\.)kuaishou\.com$
(^|\.)gifshow\.com$
(^|\.)yximgs\.com$
(^|\.)ksapisrv\.com$

建议逐条验证,不要一次性封锁大量共享域名。

特别注意:

  • amemv.com:先观察 Query Log,再决定是否封锁。
  • 不要直接封锁 snssdk.com。
  • 不要直接封锁 pstatp.com。
  • 不要直接封锁 byteimg.com。
  • 不要直接封锁 bytedance.net。
  • 微信相关域名应通过实际请求日志判断,避免影响微信聊天、登录、支付和其他功能。

微信视频号的过滤需要先观察真实请求域名,再逐项测试,不能简单地把所有腾讯域名封锁。

8. 日常维护与故障检查

8.1 查看容器状态

docker compose ps

8.2 查看健康状态

docker inspect pihole \
  --format '{{.State.Status}} {{.State.Health.Status}}'

正常状态:

running healthy

8.3 查看容器日志

docker logs --tail 100 pihole

8.4 更新 Gravity

docker exec -it pihole pihole -g

8.5 检查网络连接

docker inspect pihole \
  --format '{{json .NetworkSettings.Networks}}'

重点检查两个网络及其 IP 地址。

8.6 备份

建议定期备份:

/vol1/1000/Docker/pihole/etc-pihole
/vol1/1000/Docker/pihole/compose.yaml

其中:

  • etc-pihole 保存 Pi-hole 的配置及相关数据。
  • compose.yaml 保存容器部署配置。
  • 备份时不要把管理密码明文发送到公开位置。

9. 已知限制与后续注意事项

9.1 IPv6 前缀变化

当前 IPv6 网络使用:

240e:3a6:1e18:a160::/64

如果运营商重新分配 IPv6 前缀,需要检查并同步更新:

  1. Docker IPv6 网络 subnet。
  2. Docker IPv6 gateway。
  3. Pi-hole IPv6 地址。
  4. TP-Link DHCPv6 下发的 DNS 地址。
  5. Windows 客户端获得的 IPv6 DNS 地址。

目前尚未实现自动检测和更新。建议后续单独设计前缀变化监测方案。

9.2 DNS 绕过

Pi-hole 只能控制经过它的 DNS 请求。

以下情况仍可能绕过:

  • 浏览器启用 DNS over HTTPS(DoH)。
  • 应用内置 DNS。
  • DNS over TLS(DoT)。
  • VPN 或代理软件自行处理 DNS。
  • 设备手动设置其他 DNS。

因此,当前部署能够实现家庭网络的常规 DNS 过滤,但不能保证所有应用、所有协议都无法绕过。

9.3 容器重建

目前已经完成:

  • Compose 双网络声明。
  • Compose 语法检查。
  • 现有容器双栈连接检查。
  • docker compose up -d --no-recreate。
  • 容器健康状态检查。

尚未完成:

  • 停止并重建容器后 IPv6 是否自动恢复的实际测试。

未来如需验证,应先准备维护窗口和备用 DNS 方案,避免家庭网络 DNS 服务中断。


10. 当前部署状态总结

项目状态
Pi-hole Docker 部署已完成
IPv4 Macvlan正常
IPv6 Macvlan正常
Compose 双网络声明已配置
Compose 语法检查通过
容器运行状态running
容器健康状态healthy
TP-Link DHCPv4 DNS已配置
TP-Link DHCPv6 DNS已配置
Windows IPv4 DNS 测试通过
Windows IPv6 DNS 测试通过
百度正常解析通过
抖音 DNS 拦截通过
中文清单已添加,需以 Gravity 更新结果确认下载情况
容器重建后的 IPv6 持久性尚未实测
IPv6 前缀变化自动处理尚未实现

当前结论: Pi-hole 已经在家庭网络中正常提供 IPv4 + IPv6 双栈 DNS 服务,Windows 客户端的正常解析和抖音拦截均已验证。后续重点是确认中文清单下载成功、观察误拦截情况,以及规划 IPv6 前缀变化的处理方案。