补充:证书自动续约检查、故障诊断与重新签发
完成 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;
这样可以确认:
- 域名是否仍然由 Nginx 提供服务;
- Nginx 实际读取的是哪个证书文件;
- 后续
--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.sh 的 dns_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 如果曾经出现在公开文章、聊天记录、截图或代码仓库中,应立即在腾讯云控制台废弃旧密钥并重新创建新的密钥。