核心是配置Nginx透传.well-known/acme-challenge路径供Certbot HTTP-01验证,使用webroot模式申请证书,并通过systemd timer定期执行certbot renew --post-hook "nginx -s reload"实现安全自动续期。

通过 Nginx 配合 Certbot 实现证书自动化续期,核心是让 Certbot 在不中断服务的前提下完成 HTTP-01 挑战,并用 systemd 或 cron 定期触发续期与重载 Nginx。关键在于配置好 Nginx 的 ACME 验证路径、确保 Certbot 有权限操作证书和重载服务,且续期脚本具备错误处理能力。
确保 Nginx 正确暴露 `.well-known/acme-challenge` 路径
Certbot 默认使用 HTTP-01 验证,需让 Nginx 将 /.well-known/acme-challenge/ 请求直接映射到 Certbot 的验证目录(通常是 /var/www/html/.well-known/acme-challenge/),不经过代理或重写干扰。
在对应 server 块中添加:
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
default_type "text/plain";
}
注意:
- 不要用 alias,避免路径拼接错误;推荐用 root + 精确前缀匹配(^~);
- 确保 /var/www/html/.well-known/acme-challenge/ 目录存在且 Nginx 进程可读;
- 若站点启用了 HTTPS 强制跳转,需确保该路径在 HTTP server 中可访问(Let’s Encrypt 不走 HTTPS 验证)。
使用 Certbot 的 webroot 插件完成首次申请与续期
相比 standalone 模式,webroot 模式复用现有 Nginx,无需停服,更稳定。
- 首次申请证书(以 example.com 为例):
sudo certbot certonly --webroot -w /var/www/html \ -d example.com -d www.example.com
- 成功后证书位于
/etc/letsencrypt/live/example.com/; - 在 Nginx 的 HTTPS server 块中引用:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
- 验证续期是否可用:
sudo certbot renew --dry-run
若输出 ** DRY RUN: simulating 'certbot renew' close to cert expiry 并显示 success,说明路径与权限正常。
配置自动续期任务(推荐 systemd timer)
比传统 cron 更可靠,支持依赖检查、日志集成和失败通知。
创建定时器服务:
# /etc/systemd/system/certbot-renew.service [Unit] Description=Certbot Renewal Wants=network-online.target <p>[Service] Type=oneshot ExecStart=/usr/bin/certbot renew --quiet --post-hook "/usr/sbin/nginx -s reload" User=root</p>
# /etc/systemd/system/certbot-renew.timer [Unit] Description=Run Certbot twice daily for renewal <p>[Timer] OnCalendar=<em>-</em>-* 04:00,16:00 Persistent=true</p><p>[Install] WantedBy=timers.target</p>
启用并启动:
sudo systemctl daemon-reload sudo systemctl enable --now certbot-renew.timer sudo systemctl list-timers | grep certbot
说明:Certbot 自带 30 天内过期才续的逻辑,两次定时不会重复执行;--post-hook 确保续成功后立即重载 Nginx,生效新证书。
增强健壮性:添加日志与失败告警(可选)
在 ExecStart 后追加日志记录:
ExecStart=/usr/bin/certbot renew --quiet \ --post-hook "/usr/sbin/nginx -s reload" \ --deploy-hook "/bin/sh -c 'echo \$(date): Renewal done. | logger -t certbot'" \ --renew-hook "/bin/sh -c 'echo \$(date): Certificate renewed for \$RENEWED_DOMAINS. | logger -t certbot'"
若需邮件提醒失败,可在 --deploy-hook 或 --post-hook 中加入 mail -s "Certbot failed" admin@example.com ,配合 <code>stderr 重定向捕获错误。
不复杂但容易忽略的是权限与路径一致性——Nginx 要能读验证文件,Certbot 要能写证书并执行 reload,systemd 要按预期触发。只要每步验证到位,整个流程就可长期无人值守运行。


















