Go语言用autocert实现HTTPS自动续期必须满足三个硬性条件:80端口公网可达、域名真实解析、证书缓存持久化;缺一则报“no certificate for domain”或静默失败,且需显式配置HostPolicy、禁用CDN强制HTTPS、避免localhost等Let’s Encrypt不支持的域名。

Go 语言用 autocert 做自动续期,不是“配完就跑”,而是必须满足三个硬性条件:80 端口可被公网访问、域名真实解析、证书缓存持久化。缺一不可,否则你会卡在 no certificate for domain 或静默失败。
autocert.Manager 为什么一直报 “no certificate for domain”
这不是证书没申请到,是 ACME HTTP-01 挑战压根没触发——autocert.Manager 需要一个干净的 :80 端口来响应 /.well-known/acme-challenge/ 请求,但它不会自己起服务。
- 必须单独启动一个
http.Server监听:80,且 只注册mgr.HTTPHandler(nil),不能混入你自己的路由或中间件 - 云服务器(如阿里云、腾讯云)要检查安全组和 CDN:CDN 若开启“强制 HTTPS”,会拦截所有 HTTP 请求,导致挑战失败
-
HostPolicy必须显式设置,例如autocert.HostWhitelist("example.com", "www.example.com");空策略或默认值会直接拒绝所有域名 - 本地开发别用
localhost或内网 IP:Let’s Encrypt不验证它们,会报acme: error: 400 :: ... :: urn:ietf:params:acme:error:rejectedIdentifier
autocert 和 certmagic 选哪个
certmagic 是更务实的选择,尤其对生产环境:
-
autocert在 Go 1.19+ 后对通配符证书支持弱、无法复用已有账户密钥、续期逻辑偶有跳过;而certmagic封装更稳,社区活跃度高 -
certmagic默认启用 OCSP Stapling,减少 TLS 握手延迟;autocert要手动实现GetCertificate+ 缓存逻辑才能做到 -
certmagic.CleanUpOwnFiles()可安全清理过期证书文件;autocert没提供类似接口,手动删容易误删正在使用的证书 - 注意:
certmagic不兼容http.ServeTLS的原始用法,必须用certmagic.HTTPS或certmagic.Listen启动服务,否则证书不会加载
证书不重申请的关键:Cache 和 staging 配置
每次重启都重申请,说明证书没落盘或路径/权限出错。
立即学习“go语言免费学习笔记(深入)”;
- 必须显式配置
Cache:用autocert.DirCache("./certs")或&certmagic.FileStorage{Path: "./certs"},别依赖默认路径(如~/.cache/golang-autocert),容易因用户权限或容器环境失效 - 开发阶段务必用 staging CA:
autocert.Manager设Client: &acme.Client{DirectoryURL: "https://acme-staging-v02.api.letsencrypt.org/directory"};certmagic则设CA: certmagic.CAStaging,否则 5 分钟失败 5 次就会被限速 - 邮箱不能为空:
certmagic首次运行需注册 ACME 账户,填假邮箱会报acme: error code 400 "urn:ietf:params:acme:error:invalidContact" - 私钥文件权限必须是
0600,Linux 下若为0644,Go 会报tls: failed to find any PEM data in certificate input(实际是权限拒绝,不是格式错误)
自动续期为什么没反应
它确实在后台跑,但默认完全不打日志,失败了你也看不到。
-
certmagic续期靠 goroutine 异步执行,默认每 24 小时检查一次;autocert也类似,但不暴露调度控制点 - 必须显式启用日志:比如
certmagic.DefaultLogger = log.New(os.Stderr, "[certmagic] ", log.LstdFlags),否则续期失败只会静默吞掉 - 证书链必须完整:用
fullchain.pem,不是cert.pem;可用openssl verify -CAfile fullchain.pem cert.pem验证是否有效 - 路径要用绝对路径:
filepath.Abs("cert.pem"),相对路径在不同工作目录下会崩,报open ./cert.pem: no such file or directory
最常被忽略的是日志关闭和 staging 切换——证书快过期了,程序还在用生产环境狂试,结果被限速锁死,连 staging 都连不上。动手前先确认缓存目录可写、80 端口真能从外网 curl 通、邮箱和域名都真实有效。


















