NGINX搭建DoT服务器Android私有DNS失效报SSL证书过期错误
问题根因
该问题是Android端校验DoT服务器证书时判定证书过期导致,核心触发原因通常为以下三类:
- Let's Encrypt默认证书链兼容性问题:当前Let's Encrypt默认签发的证书会附带已过期的DST Root CA X3交叉签名链,未内置ISRG Root X1根证书的Android系统会优先追溯到该过期根证书,最终判定证书整体过期;而kdig等桌面端工具使用的根证书库已内置ISRG Root X1,会直接信任该根证书跳过旧的交叉签名链,因此请求正常。
- 证书更新后未重载NGINX:Certbot自动更新证书后如果未配置重载钩子,NGINX内存中仍会加载旧的过期证书,磁盘上的新证书不会生效,此时你本地查询磁盘证书状态正常,但NGINX实际返回的是过期证书。
- SSL配置兼容性缺失:NGINX未配置Android私有DNS要求的ECDH曲线、OCSP装订等必要参数,也可能导致Android端证书校验失败。
排查步骤
- 首先验证NGINX实际返回的证书有效期,执行命令:
openssl s_client -connect my.dns.server:853 -servername my.dns.server | openssl x509 -noout -dates
查看输出的notAfter时间,如果已过期说明NGINX未加载新证书,直接执行重载操作即可。 - 验证证书链配置,执行命令:
openssl s_client -connect my.dns.server:853 -servername my.dns.server
查看返回的证书链末尾是否存在DST Root CA X3相关条目,存在则说明使用了旧交叉签名链。 - 检查Certbot自动更新钩子配置,确认是否配置了证书更新后自动重载NGINX的逻辑。
解决方案
- 针对证书链兼容性问题,执行命令切换为纯ISRG Root X1链:
certbot renew --preferred-chain "ISRG Root X1"
执行完成后重载NGINX:systemctl reload nginx - 配置证书自动更新钩子,编辑Certbot的renew配置文件(通常位于
/etc/letsencrypt/renewal/my.dns.server.conf),在[renewalparams]段添加:renew_hook = systemctl reload nginx
确保后续证书自动更新后会自动重载NGINX加载新证书。 - 优化NGINX SSL配置提升Android兼容性,在原有配置基础上添加以下参数:
ssl_ecdh_curve prime256v1:X25519; ssl_stapling on; ssl_stapling_verify on;
调整后重载NGINX配置即可。
内容的提问来源于stack exchange,提问作者Atrox1449
相关产品推荐
相关产品推荐

