基于 OpenWrt、AdGuard Home 与 Tailscale 构建全网去广告方案:架构设计与避坑指南

2026年1月7日 | Ruichen Zhou
网络架构AdGuard HomeOpenWrtTailscaleDNS

这篇文章记录的是一次家庭网络架构的重构实践,也是我在 AdGuard Home 去广告这条路上的第三次迭代。

目标非常明确:利用家庭局域网中部署的 AdGuard Home,实现对所有设备(包括家中的 PC/IoT 设备,以及漫游在外的 MacBook、手机)的统一广告拦截和隐私保护。同时,通过合理的“控制与数据分离”,解决老旧路由器的性能瓶颈,确保在启用加密隧道(Tailscale)时,依然保持千兆级的网络体验。

背景:之前的两次尝试

在之前的文章中,我尝试过两种方案:

  1. 旁路由 + 手动DNS方案详见这篇文章

    • 在 OpenWrt 旁路由上运行 AdGuard Home
    • 每个设备需要手动设置 DNS 指向旁路由
    • 局限性:只能在局域网内生效,出门在外无法享受去广告
  2. 路由器全包方案的尝试与放弃详见这篇文章

    • 尝试在路由器上同时运行 AdGuard Home + IPv6 relay
    • 问题:路由器内存和存储空间吃紧,配置复杂度高
    • 结果:最终退回到简单方案

这次方案的目标

经过前两次的踩坑,我意识到:

  • 需求 1:全网覆盖——无论在家里还是外面,所有设备都能享受去广告
  • 需求 2:自动化配置——不想在每个设备上手动设置 DNS

于是,这次方案的核心思路变成了:职责分离

  • OpenWrt 路由器:负责”控制”(DNS 过滤、DHCP)
  • 高性能 Windows PC:负责”数据”(流量转发、加密解密)
  • Tailscale:负责”连接”(组网、全球访问)

这种架构的好处是:既能发挥老旧硬件的剩余价值,又能保证千兆级的网络体验。

1. 角色定义与流量拓扑

在开始配置之前,必须厘清网络中各设备的“角色”以及数据流向。这是避免配置混乱的关键。

设备清单与角色分配

设备名称硬件/环境角色职责
AE86WrtOpenWrt 路由器 (512MB RAM)控制核心 (DNS & DHCP)1. 运行 AdGuard Home (AGH) 进行 DNS 过滤。
2. 运行 Tailscale (非 Exit Node) 作为内网入口。
3. 负责 DHCP 地址分配。
ThinkBookWindows PC (i7 CPU)数据核心 (Exit Node)1. 运行 Tailscale Exit Node。
2. 利用高性能 CPU 处理繁重的流量加密/解密转发。
3. 7x24小时在线(设置不睡眠)。
MacBook/PhonemacOS / Android客户端无论在内网还是外网,均通过 Tailscale 接入网络,享受去广告服务。

场景流量分析

这是最容易产生误解的部分:不同的连接模式下,DNS 和业务流量走的路径是完全不同的。

场景 A:局域网内设备 (LAN Clients)

  • IP 获取:通过路由器 DHCP 获取内网 IP (192.168.2.x)。
  • DNS 流量:DHCP 下发 DNS 指向路由器 IP -> AdGuard Home -> 上游 DoH。
  • 业务流量:直接通过路由器网关访问互联网(不经过 Tailscale)。

场景 B:远程设备 - 仅组网 (No Exit Node)

  • 连接方式:Tailscale 在线,未开启 Exit Node。
  • DNS 流量:Tailscale 拦截 DNS 请求 -> 隧道 -> 路由器 AdGuard Home。
  • 业务流量:直接走设备当前的物理网络(如 4G/咖啡厅 Wi-Fi)访问互联网。
  • 适用场景:仅需要去广告,或访问家庭内网 NAS 文件。

场景 C:远程设备 - 全流量代理 (With Exit Node)

  • 连接方式:Tailscale 在线,Exit Node 选择 “ThinkBook”。
  • DNS 流量:Tailscale 拦截 DNS 请求 -> 隧道 -> 路由器 AdGuard Home。
  • 业务流量:隧道 -> ThinkBook (Windows) -> 解密转发 -> 互联网。
  • 适用场景:需要家庭公网 IP 访问受限资源,或公共 Wi-Fi 环境下保护隐私。

2. 实施阶段一:局域网 DNS 接管 (OpenWrt)

首先确保局域网内的设备能用上 AdGuard Home。OpenWrt 默认使用 dnsmasq 监听 53 端口,我们需要进行端口置换。

步骤 1:迁移 dnsmasq 并部署 AGH

保留 dnsmasq 负责 DHCP,但将其 DNS 监听端口移走:

# 1. 修改 dnsmasq 监听端口为 5300
uci set dhcp.@dnsmasq[0].port='5300'
uci commit dhcp
/etc/init.d/dnsmasq restart

# 2. 部署 AdGuard Home
# 在 AdGuard Home 初始化向导中,将管理端口设为 3000,DNS 监听端口设为 53。

步骤 2:配置 DHCP 下发 DNS (关键)

仅仅修改监听端口是不够的,局域网客户端默认会把网关 (192.168.2.1) 当作 DNS。为了更稳健,我们通过 DHCP Option 6 明确告知客户端使用 AGH 的地址(通常就是路由器 LAN IP)。

在 OpenWrt 界面:网络 -> 接口 -> LAN -> DHCP 服务器 -> 高级设置 -> DHCP 选项。输入:

6,192.168.2.1

:6 代表 DNS 服务器选项。这确保了设备连上 Wi-Fi 后,DNS 依然指向运行 AGH 的路由器。


3. 实施阶段二:全网覆盖 (Tailscale)

这一步将局域网的 DNS 能力扩展到全世界。

步骤 1:配置 Global Nameservers

登录 Tailscale Admin Console,进入 DNS 页面:

Global Nameservers: 添加路由器的 Tailscale IP(例如 100.100.1.4)。

Override local DNS: 必须开启。

原理:这会强制远程设备的 OS 忽略当前的本地 DNS(如 4G 网络的 DNS),强行将解析请求送入 Tailscale 隧道,发往家里的 100.100.1.4。

步骤 2:配置高性能出口 (Windows)

为了避免路由器因处理加密流量而 OOM (内存溢出),我们将“脏活累活”交给 Windows PC。

Windows 端: 安装 Tailscale,在菜单中开启 Run as exit node。

Console 端: 在 Admin Console 的 Machines 列表中,找到 Windows 设备,点击 Edit route settings,勾选 Use as exit node。

电源设置: 务必将 Windows 的“睡眠”设置为“从不”,并关闭“合盖休眠”。

4. 验证与回滚 (Disaster Recovery)

网络基础设施改造最怕“DNS 配崩 = 全家断网”。在应用上述配置前,请务必准备好“后悔药”。

验证步骤

去广告验证 (黑洞测试):在 MacBook (连接外网热点 + Tailscale) 终端执行:

nslookup doubleclick.net

如果返回 0.0.0.0 或 ::,说明 AdGuard Home 生效。

流量路径验证:访问 ip.sb

如果显示家庭宽带 IP,说明 Exit Node 生效。

如果显示 ThinkBook 的局域网 IP (IPv6),说明内网穿透直连成功。

紧急回滚与救砖

场景 A:AdGuard Home 崩溃/无法启动

此时全家断网(无法解析域名)。

恢复方法:SSH 登录路由器,临时改回 dnsmasq 接管 53 端口。

# 停止 AGH (如果还在运行)
/etc/init.d/AdGuardHome stop
# 恢复 dnsmasq 端口
uci set dhcp.@dnsmasq[0].port='53'
uci commit dhcp
/etc/init.d/dnsmasq restart

场景 B:DNS 解析全挂,无法 SSH 回家

如果你人在外地,DNS 挂了导致无法解析域名,Tailscale 可能会断连。

预防:在远程设备上保留记录路由器的 直连 IP (Tailscale IP) 或 DDNS 的 IP 地址。SSH 连接时直接使用 IP,不依赖域名。

ssh root@100.100.1.4

场景 C:彻底断网,需要下载修复包

临时自救:手动将电脑/手机的 DNS 设置修改为 223.5.5.58.8.8.8,绕过 Tailscale/路由器 DNS,恢复基础上网能力。


5. 常见问题排查 (Troubleshooting)

1. local_ptr_upstreams 导致的解析死循环

现象:AGH 日志大量报错 connection reset,CPU 飙升。

原因:AGH 开启了“使用私人反向 DNS”,并指向了 127.0.0.1:5300 (dnsmasq)。请求链条变成了:AGH -> dnsmasq -> 系统DNS -> Tailscale DNS -> AGH,形成死循环。

解决:在 Tailscale 环境下,建议关闭 AGH 的“使用私人反向 DNS”功能,或谨慎配置上游。

2. Windows Exit Node 导致的“客户端归一化”

现象:在 AGH 日志里,所有远程设备的 DNS 请求来源 IP 都显示为 ThinkBook 的 IP (100.100.1.10)。

原因:Windows Tailscale 运行在用户态,通过 NAT 转发流量。

影响:无法区分是 iPhone 还是 Mac 发起的请求,但不影响拦截效果。这是为了性能妥协的结果。

3. Android “私人 DNS” 导致的泄漏

现象:Android 手机广告没拦住,AGH 后台没记录。

原因:Android 系统设置中开启了“私人 DNS (Private DNS)”,优先级高于 Tailscale。

解决:进入 Android 网络设置,关闭私人 DNS。


总结

通过将计算密集型的任务(流量转发)迁移到 PC,将 IO 密集型的任务(DNS 解析)留在路由器,我们成功构建了一个既具备高性能、又拥有全网去广告能力的家庭网络。这种“各司其职”的架构,对于压榨老旧硬件性能尤为有效。