sycnnj
发布于 2026-01-20 / 13 阅读

终局之战:用 AdGuard Home + OpenWrt 打造安卓原生“私人 DNS”全链路去广告指南

关键词: AdGuard Home, OpenWrt, 私人 DNS, DoT, Android 去广告, 软路由, Cloudflare, DDNS-Go, SSL 证书, 网络安全, 隐私保护


引言:一场关于“夺回控制权”的战争

在移动互联网时代,我们正在失去对设备的控制权。

当你打开手机 App,开屏广告扑面而来;当你浏览网页,运营商的 DNS 劫持让右下角弹窗不断;当你在 5G 网络下裸奔,你的每一次 DNS 查询都是明文传输,像是在互联网上大声喊出你的隐私。

传统的去广告手段(如 hosts 文件、浏览器插件)在面对 HTTPDNS 和系统级广告植入时已显疲态。而必须挂在后台的 VPN 类去广告 App,既费电又容易被系统杀后台。

有没有一种方案,既不需要安装任何 App,也不需要耗电,却能让手机在 5G/4G/WiFi 任意网络下,都能享受到家里软路由级别的强力去广告和隐私保护?

答案是肯定的。这就是 Android 9.0 引入的**“私人 DNS” (Private DNS)** 功能,配合我们自建的 AdGuard Home (DoT) 服务器。

今天,我们将从零开始,在 OpenWrt 软路由上通过 Docker 或原生插件,部署一套支持 DNS-over-TLS (DoT) 的全球化去广告服务。这不是一篇简单的流水账,这是夺回数字领土控制权的“作战手册”。


第一章:技术演进与对抗——为什么必须是 DoT?

在开始部署之前,我们需要理解我们在和谁对抗,以及为什么要选择 DoT。

1.1 DNS 的至暗时刻:明文 UDP 53

在互联网早期,DNS 默认使用 UDP 53 端口进行明文传输。

  • 运营商劫持:ISP 可以轻易篡改你的查询结果,把你导向广告页面。

  • 中间人监听:任何经过的路由节点都知道你想访问什么网站。

1.2 应用厂商的“背刺”:HTTPDNS

为了绕过运营商劫持,大厂(腾讯、阿里、字节)开始使用 HTTPDNS。它们通过 HTTPS 协议直接向自己的服务器请求 IP,绕过了你路由器的 DNS 设置。这就是为什么你明明设置了 AdGuard Home,某些 App 的广告依然去不掉的原因——它们根本不走你的 DNS。

1.3 破局者:DoT (DNS over TLS)

Android 的“私人 DNS”强制使用 DoT 协议(TCP 853 端口)。这是一次系统级的“降维打击”:

  1. 强制接管:只要开启私人 DNS,Android 系统底层会将所有 App(绝大多数)的 DNS 请求强制导向你的 DoT 服务器。

  2. 加密隧道:基于 TLS 加密,运营商和黑客无法窥探你的请求。

  3. 身份验证:必须校验 SSL 证书,防止假冒 DNS 服务器。

结论:自建 DoT 服务器,利用 Android 原生功能,是目前最优雅、最省电、最底层的去广告方案。


第二章:战前准备——环境与基础设施

在这一章节,我们将构建坚实的基础设施。

2.1 硬件与网络要求

  • 核心设备:运行 OpenWrt 的软路由(X86/ARM 均可)。

  • 网络环境

    • 公网 IP:IPv4 或 IPv6 均可(推荐 IPv6,移动端穿透性更好)。

    • 域名:一个托管在 Cloudflare 的域名(本文以 oool.cc 为例,我们将构建 dns.xxxx.com)。

  • 核心组件

    • luci-app-ddns-go:解决动态 IP 问题。

    • acme.sh:解决 SSL 证书问题。

    • AdGuard Home:核心 DNS 引擎。


第三章:实战部署——从零构建数字堡垒

步骤一:解决动态 IP 的痛点 (DDNS-Go)

家庭宽带的 IP 是动态的,我们需要通过 DDNS 将域名实时绑定到最新 IP。这里推荐使用 DDNS-Go,因为它对 IPv6 和 Cloudflare 的支持最完美。

  1. 获取 Cloudflare API Token

    • 登录 CF 后台 -> My Profile -> API Tokens -> Create Token。

    • 选择模板 "Edit zone DNS"

    • 关键设置:Zone Resources 选择你的域名 oool.cc

    • 注意:记下生成的 Token,不要泄露。

  2. 配置 DDNS-Go(建议在 OpenWrt 容器或插件中运行):

    • DNS 服务商:Cloudflare。

    • Token:填入上述 Token。

    • IPv4 设置

      • 启用:勾选。

      • 获取方式:通过接口获取(推荐 https://myip.ipip.net,避免网卡内网 IP 误判)。

      • Domains: dns.xxxx.com

    • IPv6 设置(强烈建议启用,为 5G 网络铺路):

      • 启用:勾选。

      • 获取方式:通过接口获取(推荐 https://ipv6.ip.sb,避免教育网接口报错)。

      • Domains: dns.xxxx.com

    • TTL 设置:设为 Auto60(1分钟),配合 2 分钟的检测频率,确保 IP 变动后瞬间恢复。

步骤二:铸造信任——自动化 SSL 证书 (acme.sh)

DoT 的核心是“信任”。Android 手机连接你的服务器时,会严格校验 SSL 证书。我们将使用 acme.sh 申请 Let's Encrypt 证书。

1. 安装环境与工具 SSH 登录 OpenWrt,执行以下命令:

Bash

opkg update
opkg install openssl-util socat
curl https://get.acme.sh | sh

注:openssl-utilsocat 是必须的依赖,很多精简版固件会缺失。

2. 导入 Cloudflare 凭据 为了让脚本能自动去 CF 添加验证记录,我们需要导入变量。

  • 获取 Account ID/Zone ID:在 CF 域名管理页面的右下角 API 栏目中查找。

Bash

export CF_Token="你的_CF_API_Token"
export CF_Account_ID="你的_Account_ID_32位字符"
export CF_Zone_ID="你的_Zone_ID_32位字符"  # 加上这个防止脚本找不到区域

3. 申请证书 (ECC 算法)

Bash

# 切换默认 CA 为 Let's Encrypt (ZeroSSL 需要注册邮箱且限制较多,LE 更稳)
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt

# 申请泛域名或单域名证书
/root/.acme.sh/acme.sh --issue --dns dns_cf -d dns.xxxx.com --keylength ec-256

如果看到绿色的 Cert success,恭喜你,最难的一步跨过去了。

4. 安装证书到指定目录

Bash

mkdir -p /etc/adguardhome/ssl
/root/.acme.sh/acme.sh --install-cert -d dns.xxxx.com --ecc \
--key-file       /etc/adguardhome/ssl/dns.key  \
--fullchain-file /etc/adguardhome/ssl/dns.cer \
--reloadcmd     "/etc/init.d/adguardhome restart"

步骤三:指挥中心——AdGuard Home 深度配置

现在我们有了域名,有了证书,开始配置 AGH 的核心加密功能。

  1. 进入 AGH 后台 -> 设置 -> 加密设置

  2. 启用加密:勾选。

  3. 服务器名称dns.xxxx.com

  4. HTTPS 端口:设置为 4433

    • 注意:不要设为 0,也不要设为 443(会被 uhttpd/nginx 占用)。AGH 必须占一个端口才能保存配置。

  5. DNS-over-TLS 端口:设置为 853(这是 Android 私人 DNS 的唯一标准端口)。

  6. 证书路径

    • 证书文件:/etc/adguardhome/ssl/dns.cer

    • 私钥文件:/etc/adguardhome/ssl/dns.key

  7. 保存配置。如果无报错,说明 SSL 加载成功。

访问控制避坑: 检查 设置 -> DNS 设置 -> 访问设置。确保“允许的客户端”一栏是空的。如果你在这里填了 192.168.1.0/24,那么你的手机在 5G 网络下就会被无情拒绝。

步骤四:打通关隘——OpenWrt 防火墙的艺术

这一步是 99% 的用户失败的原因。很多人习惯去设置“端口转发”,这是错误的!

技术原理:AGH 运行在软路由本机(如 172.20.0.1 或 192.168.x.1),对于防火墙来说,这属于 Input (输入) 流量,而不是 Forward (转发) 流量。且 IPv6 没有 NAT,更谈不上转发。

正确操作(通信规则 Traffic Rules):

  1. 进入 OpenWrt -> 网络 -> 防火墙 -> 通信规则

  2. 新建规则

    • 名称:Allow-DoT-853

    • 协议:TCP (DoT 基于 TCP)

    • 源区域:wan, wan6 (允许公网 IPv4/v6)

    • 源地址留空 (关键!不要选任何 IP)

    • 源端口必须留空! (致命坑点:客户端使用随机高位端口,填 853 会导致无法连接)

    • 目标区域设备 (Input) (关键!这是给路由器自己的流量)

    • 目标端口853

    • 动作:接受

  3. 保存并应用。

第四章:终极测试与问题排查

4.1 客户端设置

掏出你的 Android 手机:

  1. 关闭 WiFi,开启 5G 数据网络(模拟公网环境)。

  2. 设置 -> 网络和互联网 -> 私人 DNS。

  3. 选择“私人 DNS 提供商主机名”。

  4. 输入:dns.xxxx.com

  5. 保存。

4.2 状态判断

  • 成功:下方显示“已连接”,没有报错。此时打开浏览器访问网页,去 AGH 后台查询日志,能看到来自公网 IP (通常是 2409 开头的 IPv6) 的 DNS-over-TLS 请求。

  • 失败(无法连接)

    • 检查防火墙:是否误用了端口转发?源端口是否未清空?

    • 检查端口:使用站长工具或 port.ping.pe 扫描 dns.xxxx.com:853,看是否全球通。

    • 检查 IPv6:部分地区移动网络 IPv6 路由不通,尝试在 DDNS 中仅开启 IPv4 测试。

4.3 解决“回流”问题(NAT Loopback)

为了让手机回家连 WiFi 时速度更快,不绕公网: 在 OpenWrt -> 网络 -> DHCP/DNS -> 自定义挟持域名 (Hosts) 中添加: 172.20.0.1 dns.xxxx.com 这样在家时,手机会直接解析到内网 IP,通过内网传输 DoT 流量。


第五章:技术总结与展望

通过这套方案,我们实现了:

  1. 全链路加密:从手机到家中服务器,DNS 查询全程 TLS 加密,彻底告别运营商劫持。

  2. 全场景去广告:无论是在家还是在公司、在地铁(5G),只要手机开机,广告过滤规则(如 Anti-AD)就如影随形。

  3. 零损耗:利用 Android 系统级功能,无需后台挂载 VPN,耗电量几乎为零。

这场与广告商和监控者的斗争是长期的。 虽然 DoT 很强,但未来的战场属于 ECH (Encrypted Client Hello) 和 DoH3 (HTTP/3)。但在当下,拥有一台独立自主、可控的 DNS 服务器,是我们作为技术极客保护数字隐私最有力的武器。

Enjoy your clean internet!


附录:常用排查命令

  • 查看证书文件ls -lh /etc/adguardhome/ssl/

  • 测试端口监听netstat -nlp | grep 853

  • 手动申请证书/root/.acme.sh/acme.sh --issue --dns dns_cf -d dns.xxxx.com --keylength ec-256 --force


本文首发于 E路领航 ( blog.oool.cc),转载请注明出处。