文章

Certbot Nginx 插件实现证书自动续期

Certbot Nginx 插件实现证书自动续期

最近在服务器维护过程中,遇到了 SSL 证书自动续期的问题。我的服务器上运行着多个子域名服务,包括博客、Git、API 等,都需要 HTTPS 支持。

问题发现

执行 certbot renew --dry-run 测试证书续期时,发现部分域名续期失败:

The following simulated renewals succeeded:
  /etc/letsencrypt/live/api.example.com/fullchain.pem (success)
  /etc/letsencrypt/live/blog.example.com/fullchain.pem (success)
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
  /etc/letsencrypt/live/git.example.com/fullchain.pem (success)

The following simulated renewals failed:
  /etc/letsencrypt/live/chat.example.com/fullchain.pem (failure)
  /etc/letsencrypt/live/ollama.example.com/fullchain.pem (failure)

错误信息显示:

Failed to renew certificate chat.example.com with error: Could not bind TCP port 80 because it is already in use by another process on this system (such as a web server).

原因分析

检查后发现,成功续期的域名使用了 webroot 或 nginx 插件验证方式,而失败的域名使用了 standalone 验证方式。由于 Nginx 一直在运行并占用 80 端口,standalone 验证方式无法工作。

Nginx 插件工作原理

Certbot Nginx 插件能够:

  • 读取和修改 Nginx 配置
  • 在验证过程中临时添加必要的配置
  • 自动配置证书路径和 SSL 参数
  • 在整个过程中保持 Nginx 服务运行

解决方案

首先安装 Nginx 插件:

sudo apt install python3-certbot-nginx

然后对失败的域名重新申请证书:

sudo certbot --nginx -d chat.example.com
sudo certbot --nginx -d ollama.example.com

插件会自动:

  • 识别 Nginx 中的域名配置
  • 添加临时验证路径
  • 验证域名所有权
  • 安装证书并更新配置
  • 重新加载 Nginx

再次测试续期:

sudo certbot renew --dry-run

这次所有域名都成功通过了续期测试。

技术细节

Nginx 插件通过修改配置来处理验证请求,而不是创建独立的 web 服务。它会:

  1. 解析 Nginx 配置文件
  2. 添加验证用的 location 块:
    location /.well-known/acme-challenge/ {
        # 验证配置
    }
    
  3. 重新加载 Nginx 配置
  4. 配置证书路径和 SSL 参数
  5. 再次重新加载 Nginx

自动续期

配置完成后,Certbot 会创建定时任务,定期检查证书是否需要续期。由于所有域名现在都使用 Nginx 插件,续期过程将完全自动化。

经验总结

  1. 对所有域名使用相同的验证方式
  2. 运行 Nginx 服务器时,Nginx 插件是最佳选择
  3. 使用 --dry-run 选项测试续期过程
  4. 通过 /etc/letsencrypt/renewal/ 目录下的配置文件可以查看验证方式

Nginx 插件简化了证书管理流程,确保网站始终保持 HTTPS 加密,避免因证书过期导致服务中断。

License:  CC BY 4.0