补充:证书自动续约检查、故障诊断与重新签发

补充:证书自动续约检查、故障诊断与重新签发

完成 acme.sh 自动续约配置后,建议同时掌握下面这些检查命令。

证书自动续约出现问题时,不要第一时间重新申请证书,应该先判断问题发生在哪一层:

markdown 复制代码
acme.sh 是否还管理该域名
        ↓
腾讯云 DNS API 凭证是否存在
        ↓
cron 是否正常执行
        ↓
acme.sh 是否成功生成新证书
        ↓
新证书是否复制到 Nginx
        ↓
Nginx 是否 reload
        ↓
线上实际证书是否更新

一、查看 acme.sh 当前管理的所有证书

执行:

bash 复制代码
/root/.acme.sh/acme.sh --list

例如:

yaml 复制代码
Main_Domain  KeyLength  SAN_Domains  CA               Created               Renew
example.com  ec-256     *.example.com LetsEncrypt.org  2026-07-25T18:13:27Z  2026-08-23T18:13:27Z

主要关注:

  • Main_Domain:主域名
  • SAN_Domains:通配符或其他域名
  • Created:证书创建时间
  • Renew:下一次续约时间

如果某个正在使用的域名没有出现在这里,例如:

css 复制代码
Nginx 正在使用:zhideyun.cn
acme.sh --list:没有 zhideyun.cn

那么即使 cron 正常执行,acme.sh 也不会续约这个域名。

这种情况不能单纯执行 --renew,而应该重新执行 --issue,把域名重新加入 acme.sh 管理。


二、查看 Nginx 当前配置了哪些 HTTPS 域名

可以直接查看 Nginx 最终加载的配置:

javascript 复制代码
nginx -T 2>/dev/null | grep -nE 'server_name|ssl_certificate|ssl_certificate_key'

如果只想查看某个域名,例如:

javascript 复制代码
nginx -T 2>/dev/null | grep -n -B3 -A5 'zhideyun.cn'

可以看到类似:

ini 复制代码
server_name zxhrs.zhideyun.cn;

ssl_certificate     /usr/local/nginx/ssl/zhideyun.cn.pem;
ssl_certificate_key /usr/local/nginx/ssl/zhideyun.cn.key;

这样可以确认:

  1. 域名是否仍然由 Nginx 提供服务;
  2. Nginx 实际读取的是哪个证书文件;
  3. 后续 --install-cert 应该把新证书安装到哪里。

三、检查当前 Nginx 证书是否已经过期

例如:

diff 复制代码
openssl x509 \
-in /usr/local/nginx/ssl/zhideyun.cn.pem \
-noout -subject -issuer -dates -serial

输出例如:

makefile 复制代码
subject=CN = zhideyun.cn
issuer=C = US, O = Let's Encrypt, CN = E7
notBefore=May 24 10:46:31 2026 GMT
notAfter=Aug 22 10:46:30 2026 GMT

重点看:

复制代码
notAfter

它就是证书过期时间。


四、检查线上实际使用的证书

本地证书已经更新,不代表线上一定已经更新。

例如检查:

复制代码
zxhrs.zhideyun.cn

执行:

javascript 复制代码
echo | openssl s_client \
-servername zxhrs.zhideyun.cn \
-connect zxhrs.zhideyun.cn:443 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates

这条命令检查的是客户端真正访问到的 HTTPS 证书。

因此最好同时比较:

markdown 复制代码
acme.sh 内部证书
        ↓
Nginx 本地证书文件
        ↓
线上 HTTPS 证书

如果:

复制代码
acme.sh      新证书
Nginx 文件   旧证书
线上         旧证书

通常说明 --install-cert 没有正确部署。

如果:

复制代码
acme.sh      新证书
Nginx 文件   新证书
线上         旧证书

通常说明 Nginx 没有 reload,或者前面还有 CDN、负载均衡等服务。

如果:

复制代码
acme.sh      旧证书
Nginx 文件   旧证书
线上         旧证书

说明续约本身就没有成功。


五、检查腾讯云 SecretId / SecretKey

使用腾讯云 DNS API 自动验证时,需要:

复制代码
Tencent_SecretId
Tencent_SecretKey

检查当前 Shell 环境变量

为了避免直接把 Secret 输出到终端,不建议:

bash 复制代码
echo $Tencent_SecretKey

推荐使用:

bash 复制代码
for v in Tencent_SecretId Tencent_SecretKey; do
    if [ -n "$(printenv "$v")" ]; then
        echo "$v: 已配置"
    else
        echo "$v: 未配置"
    fi
done

正常:

makefile 复制代码
Tencent_SecretId: 已配置
Tencent_SecretKey: 已配置

需要注意:

ini 复制代码
export Tencent_SecretId="xxx"
export Tencent_SecretKey="xxx"

只会设置当前 Shell 环境。

退出 SSH、重新打开 Shell 或服务器重启后,这两个 export 本身不会继续存在。


六、检查 acme.sh 是否已经持久化腾讯云凭证

相比当前 Shell 环境变量,更重要的是检查:

bash 复制代码
/root/.acme.sh/account.conf

执行:

bash 复制代码
grep -E '^Tencent_Secret(Id|Key)=' /root/.acme.sh/account.conf \
| sed -E 's/=.*/=<已配置>/'

正常应该输出:

ini 复制代码
Tencent_SecretId=<已配置>
Tencent_SecretKey=<已配置>

如果完全没有输出:

复制代码
说明 account.conf 当前没有保存腾讯云 DNS API 凭证。

这会直接影响无人值守的 cron 自动续约。

acme.shdns_tencent 插件会优先读取当前环境变量;环境变量不存在时,则从 account.conf 读取。


七、持久化腾讯云 SecretId / SecretKey

假设当前已经执行:

ini 复制代码
export Tencent_SecretId="你的SecretId"
export Tencent_SecretKey="你的SecretKey"

可以持久化到 acme.sh

bash 复制代码
sed -i \
'/^Tencent_SecretId=/d;/^Tencent_SecretKey=/d' \
/root/.acme.sh/account.conf

printf "Tencent_SecretId='%s'\nTencent_SecretKey='%s'\n" \
"$Tencent_SecretId" "$Tencent_SecretKey" \
>> /root/.acme.sh/account.conf

chmod 600 /root/.acme.sh/account.conf

然后验证:

bash 复制代码
grep -E '^Tencent_Secret(Id|Key)=' /root/.acme.sh/account.conf \
| sed -E 's/=.*/=<已配置>/'

应该显示:

ini 复制代码
Tencent_SecretId=<已配置>
Tencent_SecretKey=<已配置>

这样即使:

复制代码
退出 SSH
重新登录
服务器重启
cron 自动运行

acme.sh 仍然可以从 account.conf 获取腾讯云 DNS API 凭证。

是否还需要写 /root/.bash_profile

通常不需要。

对于 acme.sh 自动续约:

bash 复制代码
/root/.acme.sh/account.conf

才是更合适的持久化位置。

如果只是为了登录服务器以后手工执行命令时也能直接使用环境变量,可以另外写入:

bash 复制代码
/root/.bash_profile

但是不要依赖 .bash_profile 给 cron 提供凭证。


八、检查自动续约定时任务

执行:

复制代码
crontab -l

如果 acme.sh 是 root 安装,也可以明确执行:

复制代码
sudo crontab -l

重点检查是否存在:

css 复制代码
acme.sh --cron

例如:

arduino 复制代码
/root/.acme.sh/acme.sh --cron --home "/root/.acme.sh"

acme.sh 安装时通常会自动创建 cron 任务。

CentOS / Rocky Linux / AlmaLinux 还可以检查 cron 服务:

lua 复制代码
systemctl status crond --no-pager

如果没有运行:

bash 复制代码
systemctl enable --now crond

九、手工执行一次自动续约检查

排查自动续约失败时,非常推荐手工执行:

css 复制代码
/root/.acme.sh/acme.sh \
--cron \
--home /root/.acme.sh \
--debug 2

不要加:

javascript 复制代码
> /dev/null

因为排错时需要看到完整输出。

重点检查是否出现:

复制代码
Tencent_SecretId
Tencent_SecretKey
dns_tencent
AuthFailure
SecretId
DNS
renew
reload
nginx

等相关错误。

正常的 cron 平时可以隐藏输出,但故障排查时一定要使用 --debug


十、域名还在 acme.sh 中:手工立即续约

首先:

bash 复制代码
/root/.acme.sh/acme.sh --list

如果能看到:

复制代码
example.com   ec-256   *.example.com

可以执行:

diff 复制代码
/root/.acme.sh/acme.sh \
--renew \
-d example.com \
--ecc \
--force \
--debug 2

其中:

css 复制代码
--force

表示即使当前没有到正常续约时间,也立即重新续约。

平时正常自动续约不需要 --force


十一、域名已经不在 acme.sh 中:重新签发

如果:

bash 复制代码
/root/.acme.sh/acme.sh --list

已经找不到该域名,那么执行 --renew 没有意义。

需要重新执行:

diff 复制代码
/root/.acme.sh/acme.sh \
--issue \
--dns dns_tencent \
-d example.com \
-d '*.example.com' \
--keylength ec-256 \
--server letsencrypt \
--dnssleep 120

例如:

diff 复制代码
/root/.acme.sh/acme.sh \
--issue \
--dns dns_tencent \
-d zhideyun.cn \
-d '*.zhideyun.cn' \
--keylength ec-256 \
--server letsencrypt \
--dnssleep 120

成功后再次检查:

bash 复制代码
/root/.acme.sh/acme.sh --list

应该重新看到:

复制代码
zhideyun.cn    ec-256    *.zhideyun.cn

这时该域名才重新进入 acme.sh 的自动续约管理范围。


十二、重新建立 Nginx 自动部署关系

仅仅 --issue 成功还不够。

还要告诉 acme.sh

复制代码
续约以后把证书复制到哪里
以及复制完成以后如何 reload Nginx

例如源码安装的 Nginx:

diff 复制代码
/root/.acme.sh/acme.sh \
--install-cert \
-d zhideyun.cn \
--ecc \
--key-file /usr/local/nginx/ssl/zhideyun.cn.key \
--fullchain-file /usr/local/nginx/ssl/zhideyun.cn.pem \
--reloadcmd "/usr/local/nginx/sbin/nginx -s reload"

如果 Nginx 使用 systemd:

diff 复制代码
/root/.acme.sh/acme.sh \
--install-cert \
-d example.com \
--ecc \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.pem \
--reloadcmd "systemctl reload nginx"

--install-cert 不只是复制一次证书。

它还会保存:

vbnet 复制代码
key-file
fullchain-file
reloadcmd

这样以后自动续约成功后,acme.sh 才能继续:

markdown 复制代码
生成新证书
    ↓
覆盖 Nginx 证书
    ↓
reload Nginx

十三、检查 Nginx 配置

安装证书以后先检查:

源码安装:

bash 复制代码
/usr/local/nginx/sbin/nginx -t

或者:

复制代码
nginx -t

正常应该看到:

csharp 复制代码
syntax is ok
test is successful

如果需要手工 reload:

bash 复制代码
/usr/local/nginx/sbin/nginx -s reload

或者:

复制代码
systemctl reload nginx

具体使用哪个命令取决于服务器 Nginx 的安装方式。


十四、重新签发完成后的最终验证

检查 Nginx 本地证书:

diff 复制代码
openssl x509 \
-in /usr/local/nginx/ssl/zhideyun.cn.pem \
-noout -subject -issuer -dates

再检查线上:

javascript 复制代码
echo | openssl s_client \
-servername zxhrs.zhideyun.cn \
-connect zxhrs.zhideyun.cn:443 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates

两个地方的证书有效期应该一致。

最后执行:

bash 复制代码
/root/.acme.sh/acme.sh --list

确认:

复制代码
Main_Domain
SAN_Domains
Created
Renew

均正常。


十五、推荐的故障排查顺序

以后再遇到 HTTPS 证书过期,不建议直接重新申请。

按照下面顺序检查最快:

bash 复制代码
# 1. acme.sh 管理了哪些域名
/root/.acme.sh/acme.sh --list

# 2. Nginx 实际使用什么证书
nginx -T 2>/dev/null | grep -nE \
'server_name|ssl_certificate|ssl_certificate_key'

# 3. 本地证书有效期
openssl x509 \
-in /usr/local/nginx/ssl/example.com.pem \
-noout -dates -subject

# 4. 检查腾讯云凭证
grep -E '^Tencent_Secret(Id|Key)=' \
/root/.acme.sh/account.conf \
| sed -E 's/=.*/=<已配置>/'

# 5. 检查 cron
crontab -l

# 6. 手工运行自动续约流程
/root/.acme.sh/acme.sh \
--cron \
--home /root/.acme.sh \
--debug 2

# 7. 检查线上实际证书
echo | openssl s_client \
-servername example.com \
-connect example.com:443 2>/dev/null \
| openssl x509 -noout -dates -subject

判断原则

acme.sh 列表没有域名

css 复制代码
重新 --issue

acme.sh 有域名,但是 DNS API 报错

复制代码
检查 Tencent_SecretId / Tencent_SecretKey

acme.sh 已产生新证书,但 Nginx 文件还是旧的

css 复制代码
检查 --install-cert

Nginx 文件已经是新证书,但线上还是旧证书

复制代码
检查 reload、CDN、负载均衡或其他 HTTPS 入口

cron 没有任务

复制代码
重新配置 acme.sh cron

十六、安全注意事项

SecretId 和 SecretKey 不要直接通过下面方式检查:

bash 复制代码
echo $Tencent_SecretKey

因为可能被终端历史、截图或者日志记录。

推荐始终只检查:

复制代码
已配置 / 未配置

并将:

bash 复制代码
/root/.acme.sh/account.conf

权限设置为:

bash 复制代码
chmod 600 /root/.acme.sh/account.conf

腾讯云 SecretKey 如果曾经出现在公开文章、聊天记录、截图或代码仓库中,应立即在腾讯云控制台废弃旧密钥并重新创建新的密钥。

相关推荐
大厂码农老A1 小时前
177K star,扒开DeepSeek Harness的营销,我看到了什么
人工智能·后端·deepseek
Lear1 小时前
Java 实现多步骤异步任务编排
后端
小强19881 小时前
告别 "if-else 地狱":PHP 中的策略模式、管道模式与责任链模式实战
后端
面试鸭1 小时前
Codex 跑进法务部,周活居然暴涨了 108 倍???
后端·面试·求职
Larcher2 小时前
从 SDD 到可交付:我如何用规范驱动 AI 做出一个 Chrome 翻译插件
前端·后端·架构
choumou_M2 小时前
SpringBoot_5:商品秒杀场景的并发实践(初步)
java·spring boot·后端
陈明勇3 小时前
Go 1.27 重磅发布:泛型方法落地、分配性能跃升,JSON v2 正式可用
后端
Zane19943 小时前
create_task 和直接 await 到底有什么不一样?asyncio 的 Task、gather 与并发数量控制
后端·python
喜欢吃豆3 小时前
5 分钟,让网页里站着一个会说话的 3D 数字人
后端