Go基于autocert的服务发起HTTP请求报x509证书过期错误如何解决
问题排查路径
从已有的异常表现可以先锁定核心矛盾:
- 报错提示的证书过期时间,和你通过
autocert托管的自有证书过期时间完全重合 - 仅特定API请求报错,其他API正常,且本地无autocert加载逻辑的测试代码可正常访问该API
- 12月26日证书过期前全链路运行正常
分步排查动作
- 先定位出问题API的实际访问目标
打印请求时传入的完整url值,在VM上执行nslookup 该API对应的域名,和本地测试机器的解析结果做对比,确认是否存在VM上DNS解析偏差、hosts文件配置错误,把域名指向了本机/内网运行的旧服务实例的情况。 - 核对autocert的域名白名单范围
当前配置的HostPolicy仅白名单了根域名、www.前缀的子域名:- 如果该API的域名不在白名单列表内,autocert会对这类Host请求直接返回内置自签证书,不会自动申请受信任的公开证书
- 遍历
cert缓存目录下的所有证书文件,执行openssl x509 -in 证书文件路径 -noout -dates,逐个查看有效期,找到和报错中2020-12-26过期时间匹配的旧证书文件。
- 排查autocert自动续期失败的原因
autocert默认会在证书过期前30天自动触发续期,你这边证书过期后没有自动更新,通常是续期流程被阻断:- 确认VM安全组、防火墙对80端口的公网放行规则:autocert默认通过HTTP-01校验完成续期,校验请求会发送到
http://你的域名/.well-known/acme-challenge/路径,80端口被拦截会直接导致续期失败,服务会一直沿用缓存中的旧证书直至过期 - 检查
cert缓存目录的文件权限:autocert需要对目录有读写权限才能落盘新申请的证书,权限不足时新证书无法写入,服务会一直使用启动时加载的旧内存证书。
- 确认VM安全组、防火墙对80端口的公网放行规则:autocert默认通过HTTP-01校验完成续期,校验请求会发送到
- 验证VM上到目标API的TLS链路
在VM上执行curl -v https://对应API完整地址,查看返回的证书有效期:- 如果返回的确实是12月26日过期的旧证书,说明请求没有走到公网正常运行的服务实例,而是回环访问到了本机运行的、持有旧证书的服务进程。
解决方案
- 把所有需要TLS证书的API域名全部补充到
HostWhitelist列表,不要仅配置根域名和www域名 - 确保80端口公网放行规则正常,保障autocert的续期校验请求能正常到达服务
- 给
cert缓存目录配置运行账号对应的读写权限,避免新证书无法写入 - 服务内部调用自身相关API时,优先走本地直连/内网HTTP地址,不要通过公网HTTPS域名回环请求,从根源上避免本地证书未更新导致的TLS校验失败
- 如果发现缓存目录中存在过期的旧证书,可以手动删除对应文件,重启服务触发autocert重新申请有效新证书
内容的提问来源于stack exchange,提问作者TidStorm
相关产品推荐
相关产品推荐

