acme.sh自动更新证书,重启Nginx生效脚本
acme.sh 是一款常用的免费 SSL 证书自动签发和续期工具,但证书更新后 Nginx 并不会自动加载新证书,需要手动重启或重载才能生效。
本文提供一套可直接落地的脚本方案,让 acme.sh 在续期成功后自动重启 Nginx,适合使用 Nginx 作为 Web 服务器的零基础用户。
适用场景与前置条件
这套方案适合已经用 acme.sh 签发过证书、服务器上运行着 Nginx 的情况。
操作前请确认:
- acme.sh 已安装,通常位于
/root/.acme.sh/目录。 - Nginx 已安装并正在运行,配置文件路径已知(如
/etc/nginx/nginx.conf)。 - 当前用户有权限执行
nginx -s reload或systemctl reload nginx。 - 证书已通过 acme.sh 签发,并且 Nginx 配置中引用了正确的证书路径。
如果尚未安装 acme.sh,可先执行官方安装命令(以实际官方文档为准):
curl https://get.acme.sh | sh -s email=你的邮箱
安装后重新登录终端,或执行 source ~/.bashrc 使 acme.sh 命令生效。
编写证书更新后重启 Nginx 的脚本
acme.sh 支持在证书续期成功后执行自定义命令,通过 --reloadcmd 参数指定。
最直接的方式是在签发或续期时加入重启命令。
方法一:签发时直接指定 reloadcmd
如果还没有签发证书,可以在签发命令中加上 --reloadcmd:
acme.sh --issue -d example.com --nginx --reloadcmd "systemctl reload nginx"
如果已经签发过证书,可以用 --install-cert 重新安装并指定 reloadcmd:
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
这样每次 acme.sh 自动续期成功后,都会自动执行 systemctl reload nginx,让 Nginx 重新加载证书文件。
方法二:独立脚本配合 crontab
如果不想修改 acme.sh 的配置,也可以写一个独立脚本,先执行续期,再重启 Nginx。
创建脚本文件:
vi /root/renew_cert.sh
写入以下内容:
#!/bin/bash
# 执行 acme.sh 续期,--cron 表示静默模式
/root/.acme.sh/acme.sh --cron --home /root/.acme.sh
# 检查续期命令的退出状态
if [ $? -eq 0 ]; then
# 续期成功,重载 Nginx
systemctl reload nginx
echo "$(date) 证书续期成功,Nginx 已重载" >> /var/log/cert_renew.log
else
echo "$(date) 证书续期失败,请检查" >> /var/log/cert_renew.log
fi
赋予执行权限:
chmod +x /root/renew_cert.sh
然后添加定时任务,比如每天凌晨 3 点执行:
crontab -e
加入一行:
0 3 * * * /root/renew_cert.sh
保存后,系统会每天自动执行脚本。
acme.sh 自身也有定时任务,但独立脚本能更明确地控制重启逻辑。
避坑指南:这些细节容易出错
- 权限问题:
systemctl reload nginx通常需要 root 权限,确保脚本以 root 用户运行,或在 crontab 中使用 root 账户。 - 路径错误:acme.sh 默认安装在
/root/.acme.sh/,如果自定义了安装路径,脚本中要写实际路径。 - Nginx 配置未引用新证书:如果 Nginx 配置中证书路径写错,即使重载也不会生效。检查
ssl_certificate和ssl_certificate_key指向的文件是否正确。 - reload 与 restart 的区别:
reload是平滑重载,不会中断现有连接;restart会重启服务,可能造成短暂中断。推荐用reload。 - 日志记录:建议在脚本中记录执行结果,方便后续排查。
验证证书是否生效
执行完脚本后,可以通过以下方式确认新证书已生效:
- 查看 Nginx 错误日志:
tail -f /var/log/nginx/error.log,看是否有证书加载报错。 - 使用
openssl检查线上证书有效期:
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -dates
- 浏览器访问网站,点击地址栏锁图标,查看证书有效期是否已更新。
如果发现证书未更新,先检查 acme.sh 的续期日志:/root/.acme.sh/acme.sh.log,再确认 Nginx 是否成功重载。
常见疑问
acme.sh 自动续期后,为什么 Nginx 没有加载新证书?
因为 acme.sh 只负责更新证书文件,不会主动通知 Nginx。
必须通过 reloadcmd 或独立脚本触发 Nginx 重载。
脚本执行了但证书还是旧的,怎么办?
检查 Nginx 配置中引用的证书路径是否与 acme.sh 安装证书的路径一致。
如果使用了 --install-cert,确认 --key-file 和 --fullchain-file 指向正确。
多久执行一次续期脚本比较合适?
acme.sh 默认在证书到期前 30 天自动续期,建议每天执行一次脚本即可。
过于频繁的续期请求可能触发 Let's Encrypt 的速率限制。
可以用 nginx -s reload 代替 systemctl reload nginx 吗?
可以,两者效果相同。
如果系统使用 systemd 管理 Nginx,推荐用 systemctl reload nginx,更规范。
按照以上步骤配置后,acme.sh 就能在证书更新后自动重启 Nginx,确保证书始终有效。
如果遇到异常,优先检查脚本权限、路径和 Nginx 配置,再查看日志定位问题。