TL;DR:证书错误 90% 的情况是这三个原因——
① 系统时间不对(手机改回自动时间);
② 你用的是自签证书的自建 DNS,但根证书没装到设备上(iOS 尤其要手动去"证书信任设置"里打开);
③ hostname 填错了,和证书上的域名对不上。
先按这三条排查,大部分证书报错都能解决。
典型报错长什么样?
不同设备上,私人 DNS 证书错误的提示文案不一样,但本质都是同一件事:你的设备不信任这台 DNS 服务器的 TLS 证书。
安卓常见提示
- "无法验证服务器身份"(Cannot verify server identity)
- "私人 DNS 服务器无法访问"(Private DNS server cannot be accessed)——这个提示有时候也是证书问题导致的
- 保存 hostname 后直接弹出红色错误
iPhone / iPad 常见提示
- 安装描述文件后提示 "未受信任"
- 设置 → 通用 → 关于本机 → 证书信任设置里,对应证书是灰色的
- DoT 连接静默失败,实际走了明文 DNS
Windows 常见提示
- 配置 DoH 后提示 "此服务器的证书无效"
- 事件查看器里出现 DNS 客户端错误事件
原因一:系统时间错误(最容易被忽略)
TLS 证书都有有效期(起止日期),设备校验证书时第一件事就是看"现在这个时间,证书在不在有效期内"。如果你手机的时间不准——比如慢了几天、快了几年——系统就会认为证书"还没生效"或"已经过期",直接报证书错误。
为什么会时间不对?
- 手机没电自动关机后,时间重置了
- 手动改过时间忘了改回来
- 旅行跨时区后没开自动时区
- 某些山寨机或刷机包的时间同步有 bug
解决步骤
安卓:
- 设置 → 系统 → 日期和时间
- 打开 "自动设置日期和时间"(或"使用网络提供的时间")
- 打开 "自动设置时区"
- 重启手机,再试私人 DNS
iPhone:
- 设置 → 通用 → 日期与时间
- 打开 "自动设置"
- 确认时区正确
- 重启
Windows:
- 右下角时间 → 右键 → 调整日期/时间
- 打开 "自动设置时间"
- 点"立即同步"
- 重启网络
验证:改完时间后,重新打开私人 DNS 设置,看证书错误是否消失。大部分情况下,时间一对,证书错误立刻就好。
原因二:自签证书没安装/没信任
如果你用的是自建 DNS 服务器(比如自己搭的 AdGuard Home),并且用的是自签证书(不是 Let's Encrypt 这种公共 CA 签发的),那设备默认是不信任这张证书的——因为自签证书不在系统的受信任根证书列表里。
iOS 特别注意:要手动开两级信任
iOS 对自签证书的管控非常严格,你就算把根证书装到设备上了,默认也是不生效的,必须手动去"证书信任设置"里打开开关:
- 先安装描述文件(设置 → 通用 → VPN与设备管理 → 已下载的描述文件)
- 然后去:设置 → 通用 → 关于本机 → 拉到最底部 → 证书信任设置
- 你会看到刚装的根证书,旁边有个开关——把它打开
- 系统会弹警告,点"继续"
- 重启设备
这一步是 iOS 独有的,很多人卡在这一步:描述文件装了,但忘了开第二级信任开关,结果 DoT 一直连不上。
安卓信任自签证书
安卓相对宽松一些:
- 设置 → 安全 → 加密与凭据 → 安装证书
- 选择你的根 CA 证书文件
- 给证书命名,用途选"VPN 和应用"
- 安装完成后,去"受信任的凭据"里确认它在"用户"标签页下
- 重启私人 DNS 设置
更好的替代方案:用公共 CA 证书
其实自建 DNS 没必要用自签证书。现在有很多免费的公共 CA(如 Let's Encrypt),可以给你的域名签一张正式证书,设备原生就信任,不用折腾安装根证书。如果你用 AdGuard Home,配合 Nginx 反代 + Let's Encrypt 证书,是最省心的方案。
原因三:hostname 和证书上的域名不匹配
TLS 证书是绑定域名的。你填的 hostname 必须和证书上写的域名完全一致(包括子域名、通配符匹配),否则设备会报"域名不匹配"的证书错误。
常见不匹配场景
| 你填的 hostname | 证书上的域名 | 是否匹配 |
|---|---|---|
dns.google | dns.google | ✅ 匹配 |
one.one.one.one | one.one.one.one | ✅ 匹配 |
myserver.com | *.myserver.com | ✅ 通配符匹配 |
ns1.myserver.com | myserver.com | ❌ 不匹配 |
1.1.1.1 | one.one.one.one | ❌ 不匹配(IP 和域名不同) |
dns.myserver.com | dot.myserver.com | ❌ 不匹配 |
解决方法
- 确认你的 DNS 服务商给你的准确 hostname 是什么——直接复制粘贴,不要手打
- 如果你自建的,检查证书的 CN(通用名称)和 SAN(主题备选名称)字段,确保你填的 hostname 列在里面
- 安卓私人 DNS 只接受 hostname,不接受 IP 地址——填 IP 一定会证书错误
原因四:中间设备拦截了 TLS 连接
如果你在公司网络、学校网络、或装了某些杀毒软件,可能有中间设备在做 TLS 拦截(中间人攻击防护/内容过滤)。这些设备会替换 DNS 服务器的证书,用自己的证书重新签名——如果你的设备不信任这个中间设备的根证书,就会报证书错误。
怎么判断是中间设备在搞鬼?
- 在家 Wi-Fi 下私人 DNS 正常,到公司就报证书错误 → 公司网络有拦截
- 关掉杀毒软件后证书错误消失 → 杀毒软件在拦截
- dnsleaktest 显示的 DNS 服务器不是你配的那台 → 被劫持了
解决方法
- 在公司网络下,暂时关闭私人 DNS,用公司的 DNS
- 把公司/杀毒软件的根证书安装到设备上并信任
- 或者改用 DoH(走 443 端口,很多中间设备只拦 853 端口的 DoT)
验证证书错误是否解决
排查完之后,怎么确认证书错误真的修好了?
- 打开私人 DNS 设置,确认没有红色错误提示
- 访问 dnsleaktest.com,点 Extended Test
- 看列出的 DNS 服务器是不是你配的那台
- 如果是,说明 DoT 连接成功,证书校验通过
FAQ
Q:安卓提示"无法验证服务器身份",但我用的是公共 DNS(Google/Cloudflare),不是自建的,怎么会证书错误?
A:公共 DNS 的证书是公共 CA 签的,理论上不会有信任问题。出现这个提示,最可能是系统时间不对,或者你的网络中有中间设备在拦截 TLS 连接。先检查时间,再换个网络(比如手机热点)测试。
Q:iOS 装了描述文件,为什么 dnsleaktest 还是显示运营商 DNS?
A:你大概率忘了开第二级信任。去 设置 → 通用 → 关于本机 → 证书信任设置,把你的根证书开关打开,重启设备再测。
Q:自建 AdGuard Home 用自签证书太麻烦了,有没有简单的办法?
A:有。用 Let's Encrypt 申请一张免费证书,配合 Nginx 反代 DoT 端口。这样设备原生信任,不用装根证书,最省心。如果你嫌自建麻烦,也可以直接用公共加密 DNS 服务——常见的 DoH/DoT 地址可以参考 免费加密DNS服务:DoH/DoT 地址与一键配置,开箱即用,完全不会有证书信任问题。
Q:证书错误和"私人 DNS 无法访问"是一回事吗?
A:不完全一样,但表现很像。证书错误是 TLS 握手阶段就失败了;无法访问可能是网络不通、端口被封、服务器宕机。两者都会导致 DoT 连不上,排查思路也类似:先看时间、再看网络、最后看证书。
参考来源
- RFC 7858: Specification for DNS over TLS — IETF Datatracker — 支撑 DoT TLS 握手、证书校验等协议机制。
- Apple Support: List of available trusted root certificates in iOS — 支撑 iOS 证书信任设置路径(设置→通用→关于本机→证书信任设置)、根证书三级分类(Trusted/Always Ask/Blocked)。
- Google Public DNS: Secure transports for DNS — 支撑 Google DoT/DoH 证书要求、TLS 1.2/1.3 支持等事实。
- Android Developers: Android 10 enterprise changes — 支撑安卓 Private DNS API、严格证书校验模式等官方行为。