HTTPS 证书自动续期的两种姿势:certbot 与 acme.sh 实战
很多个人项目和小型服务都在用 Let’s Encrypt 的免费证书,但它只有 90 天有效期。手动续期迟早会忘——忘一次,线上就是一次证书过期事故。把续期做成自动化,才是正经解法。下面介绍两种最常用的自动化方案:certbot 和 acme.sh。
为什么是这两种
certbot 是 Let’s Encrypt 官方推荐的客户端,功能全、文档多;acme.sh 是纯 Shell 实现的第三方客户端,零依赖、轻量,支持上百家 DNS 服务商的 API。两者各有适用场景。
方案一:certbot
Ubuntu/Debian 下安装很简单:
sudo apt install certbot python3-certbot-nginx
申请证书(Nginx 插件会自动改配置):
sudo certbot --nginx -d example.com -d www.example.com
自动续期的关键:certbot 安装时会自带一个 systemd timer(或 cron 任务),每天跑两次 certbot renew,只续期 30 天内到期的证书。可以用下面这条命令 dry-run 验证一次:
sudo certbot renew --dry-run
几点注意:
- renew 成功后需要重载 Web 服务,certbot 的 nginx 插件会自动处理;如果是 standalone 模式,记得加
--deploy-hook "systemctl reload nginx"。 - 80 端口必须可达(HTTP-01 验证用),防火墙和安全组要放行。
- 日志在 /var/log/letsencrypt/,续期失败先看这里。
方案二:acme.sh
如果服务器上不想装 Python 依赖,或者要做通配符证书(DNS-01 验证),acme.sh 更顺手:
curl https://get.acme.sh | sh -s email=my@example.com
申请证书(以 Cloudflare DNS API 为例,先导出 API Token):
export CF_Token="你的Token"
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
安装证书到固定位置,并设置重载钩子:
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.key \
--fullchain-file /etc/nginx/ssl/example.crt \
--reloadcmd "systemctl reload nginx"
acme.sh 安装时会自动写入一个 cron 任务,每天检查续期。手动验证一次:
acme.sh --cron --force
几点注意:
- DNS API 的 Token 给最小权限即可(
acme.sh文档里每家服务商都有说明),不要用全局 API Key。 - 证书默认签发到 ~/.acme.sh/ 目录,不要直接引用,用 --install-cert 拷贝到服务目录,避免升级时路径变化。
- 通配符证书只能走 DNS-01 验证,HTTP-01 不行。
常见坑
- 续期失败没人知道:两种方案都建议加一层监控——可以在 cron/deploy-hook 里发一条通知,或者用外部的证书过期监控(比如每天扫一遍域名端口 443 的证书有效期)。
- 80 端口被占用:certbot 的 standalone 模式需要独占 80 端口;Nginx 已在跑时优先用 --nginx 或 webroot 插件。
- 时钟不同步:ACME 验证对时间敏感,服务器时间漂移太大会导致验证失败,装个 chrony/nts 保底。
小结
| certbot | acme.sh |
|
|---|---|---|
| 实现语言 | Python | 纯 Shell |
| 官方支持 | Let’s Encrypt 官方 | 社区 |
| DNS API 支持 | 部分 | 上百家 |
| 适用场景 | 常规单域名/多域名 | 通配符、轻量环境、NAS/路由器 |
第一次配建议用 certbot,文档和排错资料最多;已经有通配符需求或环境极简,acme.sh 更省事。选定一种后,记得做一次 dry-run/–force 验证,并把“续期失败告警”加上——自动化最怕的就是静默失败。
- 点赞
- 收藏
- 关注作者
评论(0)