云服务器 HTTPS 证书到期前自查:acme.sh 续期失败的排查与 webroot 改造

举报
yd_292548114 发表于 2026/11/08 09:25:23 2026/11/08
【摘要】 网站跑着跑着,浏览器突然报证书过期,HTTPS 直接断掉,这种故障完全可以提前发现。Let’s Encrypt 证书只有 90 天有效期,acme.sh 的自动续期看着省心,但只要其中一环出问题,续期会在后台悄悄失败,等证书过期才暴露出来。本文记录一套实操流程:先自查证书剩余天数,再定位续期失败的原因,最后把容易失败的 standalone 模式改成更稳妥的 webroot 模式。 第一步:...

网站跑着跑着,浏览器突然报证书过期,HTTPS 直接断掉,这种故障完全可以提前发现。Let’s Encrypt 证书只有 90 天有效期,acme.sh 的自动续期看着省心,但只要其中一环出问题,续期会在后台悄悄失败,等证书过期才暴露出来。本文记录一套实操流程:先自查证书剩余天数,再定位续期失败的原因,最后把容易失败的 standalone 模式改成更稳妥的 webroot 模式。

第一步:先看证书还剩多少天

不要等浏览器报警,定期查一次。最直接的办法是在服务器上看证书文件本身:

openssl x509 -in /path/to/fullchain.cer -noout -dates

输出里 notAfter 就是到期时间。如果服务器上证书路径一时找不到,也可以在本机用 openssl 连公网 443 端口查:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates

建议在到期前 30 天就处理:Let’s Encrypt 允许提前 30 天续期,acme.sh 的默认定时任务也是在这个窗口触发。把检查写进每月运维清单,比事后救火便宜得多。

第二步:续期失败先看日志,不要反复重试

acme.sh 的定时任务一般在 crontab 里,类似这样:

0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

续期失败时先翻日志和邮件,常见报错就几种,对号入座:

1. 端口被占:Error renewing + 80 端口冲突。 standalone 模式续期时,acme.sh 要自己起一个临时 Web 服务独占 80 端口完成验证。如果 nginx 或其他服务正占着 80,就会失败。这是 standalone 模式最常见的死法,而且每次 cron 都会重复失败。

2. 域名解析不到本机。 验证服务器要通过公网 DNS 找到你的服务器。如果域名解析指向了别的 IP,或者解析本身就失败,验证请求根本到不了本机。

3. nginx 配置本身有问题。 这一点最容易被忽略:如果 nginx 配置里引用了一个已经解析不出来的上游(upstream),nginx -t 会直接报错,nginx 无法 reload。即使证书文件已经续下来了,旧配置也换不上去。修证书之前,先跑一次 nginx -t,确认配置本身是健康的。

定位到原因之前不要反复点续期按钮:失败的验证请求次数多了会触发频率限制,本来几分钟能修好的事,反而要等一小时才能再试。

第三步:把 standalone 改成 webroot,一劳永逸

standalone 模式要求续期瞬间独占 80 端口,和常驻的 nginx 天生冲突。更稳妥的做法是 webroot 模式:让 nginx 继续跑着,只在网站根目录下放一个验证文件,验证服务器能访问到就算通过,全程零停机。

改造分三步:

1. 在 nginx 里放行验证路径。 给需要 HTTPS 的站点加一段 location,让 /.well-known/acme-challenge/ 的请求直接读磁盘文件,不走反代和重定向:

location ^~ /.well-known/acme-challenge/ {
    alias /var/www/html/.well-known/acme-challenge/;
    default_type text/plain;
}

注意 alias 末尾的斜杠不能漏,漏了路径会拼错,验证会报 404。

2. 重新签发一次,指定 webroot。 用 --webroot 模式签一个新证书,acme.sh 会记住这个模式,以后自动续期都走同一条路:

acme.sh --issue -d example.com -d www.example.com \
  --webroot /var/www/html

3. 手动跑一次续期验证,再检查定时任务。 不要等 30 天后才知道新模式行不行,立刻手动触发一次:

acme.sh --renew -d example.com --force

成功后确认两件事:一是证书文件的 notAfter 变成了新的 90 天后,二是 nginx -t 通过并且已经 reload,让新证书真正生效。最后看一眼 crontab,确认自动续期任务还在,命令里没有残留的 --standalone 参数。

小结

  • 证书到期是可预防故障:每月查一次剩余天数,30 天窗口一到就处理
  • 续期失败先看日志:端口冲突、解析问题、nginx 配置报错,三种原因各有修法,不要盲目重试
  • 长期方案选 webroot:验证走静态文件,不抢 80 端口,不停 nginx,续期成功率明显高于 standalone
  • 每次改完验证方式,立刻手动续一次并确认 nginx -t 通过,别把验证推迟到下次自动续期
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。