Let’s Encrypt SSL证书自动续期配置:Certbot安装到全自动化维护(2026)

📝 694 字 · ☕ 2 分钟阅读

前言:为什么需要自动续期SSL证书

Let’s Encrypt 是目前最受欢迎的免费 SSL 证书颁发机构,但其证书有效期仅为 90 天。这意味着每三个月你都必须手动续期一次——如果你的站点配置了 Nginx、Apache 或其他 Web 服务器,忘记续期会导致浏览器显示”不安全”警告,直接影响用户体验和 SEO 排名。

好消息是,Let’s Encrypt 官方推荐的 Certbot 客户端内置了自动续期机制。本文将从零开始,带你完成从 Certbot 安装、首次证书签发,到自动化续期、续期后服务重载的完整配置。

第一步:安装 Certbot

Certbot 是 Let’s Encrypt 官方推荐的 ACME 客户端。根据你的操作系统选择对应的安装方式:

Ubuntu / Debian

$ sudo apt update
$ sudo apt install certbot python3-certbot-nginx    # 如果使用 Nginx
$ sudo apt install certbot python3-certbot-apache   # 如果使用 Apache

安装完成后验证版本:

$ certbot --version
certbot 2.11.0

CentOS / Rocky Linux / AlmaLinux

$ sudo dnf install epel-release
$ sudo dnf install certbot python3-certbot-nginx

第二步:首次签发 SSL 证书

Certbot 提供多种插件来签发证书。最常用的两种方式:

方式 A:使用 Nginx 插件(推荐,全自动)

如果 Nginx 配置文件已经指向你的域名,使用 Nginx 插件可以一键完成:

$ sudo certbot --nginx -d example.com -d www.example.com

Certbot 会自动:

  • 验证域名所有权(通过 HTTP-01 挑战)
  • 修改 Nginx 配置,添加 SSL 相关指令
  • 配置 301 HTTP → HTTPS 重定向(可选)

实际输出示例:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for example.com and www.example.com
Performing the following challenges:
http-01 challenge for example.com
http-01 challenge for www.example.com
Waiting for verification...
Cleaning up challenges
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
Deploying certificate
Successfully deployed certificate for example.com
Successfully deployed certificate for www.example.com
Congratulations! You have successfully enabled HTTPS!

方式 B:使用 Webroot 插件(手动配置)

如果不想让 Certbot 修改 Nginx 配置,或者使用自定义 Web 服务器:

$ sudo certbot certonly --webroot -w /var/www/example.com -d example.com -d www.example.com

这种方式仅在 Nginx 中手动添加一个 location 块指向验证目录(通常不需要手动操作,Certbot 会自动在 /.well-known/acme-challenge/ 下放置验证文件)。

第三步:验证证书文件

签发成功后,证书文件存储在 /etc/letsencrypt/live/your-domain/ 目录下:

$ sudo ls -la /etc/letsencrypt/live/example.com/
lrwxrwxrwx 1 root root  39 May 22 09:00 cert.pem -> ../../archive/example.com/cert1.pem
lrwxrwxrwx 1 root root  40 May 22 09:00 chain.pem -> ../../archive/example.com/chain1.pem
lrwxrwxrwx 1 root root  44 May 22 09:00 fullchain.pem -> ../../archive/example.com/fullchain1.pem
lrwxrwxrwx 1 root root  42 May 22 09:00 privkey.pem -> ../../archive/example.com/privkey1.pem

各文件用途:

  • cert.pem:服务端证书(仅证书本身)
  • chain.pem:中间证书链
  • fullchain.pem:服务端证书 + 中间证书链(Nginx 常用此文件)
  • privkey.pem:私钥文件(⚠️ 绝对不要公开)

Nginx 配置中的典型引用方式:

ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

第四步:测试自动续期

Certbot 安装时会自动添加一个 systemd timercron 任务,每天检查两次证书是否即将到期(到期前 30 天内会触发续期)。

首先,用 dry-run 模式测试续期流程是否正常:

$ sudo certbot renew --dry-run

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Processing /etc/letsencrypt/renewal/example.com.conf
Account registered.
Simulating renewal of an existing certificate for example.com and www.example.com
Waiting for verification...
Cleaning up challenges
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

如果输出 all simulated renewals succeeded,说明续期机制一切正常。

查看系统自带的续期定时器:

$ sudo systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Thu 2026-05-21 09:00:00 UTC; 1 day ago
    Trigger: Sat 2026-05-23 03:49:39 UTC; 18h left
   Triggers: ● certbot.service

如果系统中没有自动创建 systemd timer(例如某些旧版本),可以手动添加 cron 任务:

$ sudo crontab -e
# 每天凌晨 3:00 检查续期,如果成功则重载 Nginx
0 3 * * * /usr/bin/certbot renew --quiet && systemctl reload nginx

第五步:配置续期后服务重载

证书更新后,Web 服务器需要重新加载才能使用新证书。Certbot 的 renew 钩子可以自动完成:

方式 1:通过 deploy hook(推荐)

/etc/letsencrypt/renewal-hooks/deploy/ 目录下创建一个脚本:

$ sudo tee /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh << 'EOF'
#!/bin/bash
systemctl reload nginx || true
EOF

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh

这个脚本只会在证书 成功更新后 执行,不会在 dry-run 或续期失败时触发。

方式 2:使用 –post-hook 参数

也可以将重载命令直接写入续期命令:

$ sudo certbot renew --post-hook "systemctl reload nginx"

但 deploy hook 更加规范,因为它是 Certbot 原生支持的钩子系统,且按字母顺序执行所有 deploy 目录下的脚本。

第六步:验证自动续期是否生效

手动强制过期检查来验证整个自动续期链条:

$ sudo certbot renew --force-renewal --deploy-hook "systemctl reload nginx"

这条命令会强制续期所有证书(即使距到期还有 90 天),续期后立即重载 Nginx。查看日志确认:

$ sudo tail -20 /var/log/letsencrypt/letsencrypt.log
2026-05-22 09:15:42,123:DEBUG:certbot.renewal:Certificate renewed
2026-05-22 09:15:42,125:DEBUG:certbot.renewal:Running deploy hooks
2026-05-22 09:15:42,130:INFO:certbot.renewal:Deploy hook 'restart-nginx.sh' ran successfully

最后,检查证书到期时间:

$ sudo openssl x509 -enddate -noout -in /etc/letsencrypt/live/example.com/cert.pem
notAfter=Aug 20 09:15:42 2026 GMT

到期时间向后推移了 90 天,证明续期成功。

第七步:多域名与泛域名证书

多域名证书

一张证书可以包含多个域名,签发时用 -d 参数指定:

$ sudo certbot --nginx -d example.com -d www.example.com -d blog.example.com -d api.example.com

泛域名证书(Wildcard Certificate)

如果要保护 *.example.com 下的所有子域名,需要使用 DNS-01 挑战(因为 HTTP-01 无法验证通配符域名):

$ sudo certbot certonly --manual --preferred-challenges dns -d *.example.com -d example.com

Certbot 会提示你在 DNS 管理面板中添加一条 TXT 记录:

_acme-challenge.example.com  TXT  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

添加完成后等待 1-2 分钟让 DNS 传播,然后回车确认。

泛域名证书的续期同样需要 DNS 验证——考虑使用支持 DNS API 插件(如 Cloudflare、Aliyun DNS、DNSPod)实现全自动续期:

$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.cloudflare/credentials.ini -d *.example.com -d example.com

常见问题 FAQ

Q1: Let’s Encrypt 续期失败,提示 “No valid IP addresses” 怎么办?

A: 最常见原因是 DNS 解析问题或防火墙阻止了 80 端口(HTTP-01 验证需要)。检查步骤:

  1. 确认域名 A 记录正确指向服务器 IP:dig +short example.com
  2. 确认服务器 80 端口可访问:curl -I http://example.com/.well-known/acme-challenge/test,如果返回 404 而不是连接失败,说明端口通
  3. 检查防火墙是否放行 80 端口:sudo ufw status 确认 80/tcp 状态为 ALLOW
  4. 如果使用 CDN(Cloudflare 等),将域名切换为 DNS Only(灰色云朵)模式,或使用 DNS-01 挑战

Q2: Certbot 续期时提示 “The certificate will expire soon”,但自动续期没触发?

A: 检查 systemd timer 是否正常运行:

sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot

如果 timer 停用,手动启用:sudo systemctl enable --now certbot.timer。如果 timer 正常但依然不续期,运行 sudo certbot renew --dry-run 查看具体错误。

如果使用的是 cron 而非 systemd,确保 crontab 中指定了绝对路径:/usr/bin/certbot,因为 cron 的环境变量有限。

Q3: 如何迁移 Let’s Encrypt 证书到新服务器?

A: 最简单的做法是在新服务器上重新签发证书(因为 Let’s Encrypt 有速率限制,每周最多 50 张证书,个人站点不用担心)。如果必须迁移:

  1. 在旧服务器上打包整个 /etc/letsencrypt 目录:sudo tar czf letsencrypt-backup.tar.gz /etc/letsencrypt
  2. 将文件复制到新服务器相同路径
  3. 在新服务器上重载 Nginx:sudo systemctl reload nginx
  4. 在新服务器上运行 sudo certbot renew --dry-run 确认自动续期正常

注意:迁移后记得在新服务器上重新安装 Certbot 并确认 systemd timer 已启用。

总结

Let’s Encrypt SSL 证书的自动续期配置并不复杂:安装 Certbot → 签发证书 → 验证自动续期 → 配置 deploy hook。一旦配置完成,你基本上可以忘记证书这回事——Certbot 的 systemd timer 会每天检查两次,在到期前 30 天自动续期,deploy hook 会重载 Web 服务器。

如果你的站点已经配置了 Let’s Encrypt 但还没验证自动续期是否正常工作,建议马上运行 sudo certbot renew --dry-run 确认。还有什么比 HTTPS 证书突然过期更让人崩溃的呢?

📤 分享这篇文章