Certbot 证书自动化教程 / 第 1 章:Certbot 概述
第 1 章:Certbot 概述
1.1 什么是 Certbot
Certbot 是由电子前沿基金会(EFF)维护的开源命令行工具,用于自动获取和部署 Let’s Encrypt 签发的 SSL/TLS 证书。它实现了 ACME(Automatic Certificate Management Environment)客户端协议,能够与 Let’s Encrypt 服务器通信,完成域名验证、证书签发和自动续期。
核心功能
| 功能 | 说明 |
|---|---|
| 证书申请 | 通过 ACME 协议向 Let’s Encrypt 申请免费证书 |
| 域名验证 | 支持 HTTP-01、DNS-01、TLS-ALPN-01 多种验证方式 |
| Web 服务器集成 | 自动修改 Nginx/Apache 配置 |
| 自动续期 | 证书到期前自动续签(有效期 90 天) |
| 证书管理 | 列出、撤销、删除已管理的证书 |
Certbot 与其他 ACME 客户端对比
| 客户端 | 语言 | 特点 | 适用场景 |
|---|---|---|---|
| Certbot | Python | 功能最全面,官方推荐 | 通用场景首选 |
| acme.sh | Shell | 纯 Shell 实现,依赖少 | 嵌入式/轻量环境 |
| lego | Go | 单二进制,DNS 插件丰富 | Go 生态/DNS 验证 |
| Caddy | Go | 内置 ACME,零配置 | Web 服务器一体化 |
1.2 Let’s Encrypt 简介
Let’s Encrypt 是由互联网安全研究组(ISRG)运营的免费、自动化、开放的证书颁发机构(CA)。自 2015 年正式上线以来,已为超过 3 亿个网站提供 TLS 证书。
Let’s Encrypt 的核心原则
- 免费: 无需支付任何费用即可获取证书
- 自动化: 通过 ACME 协议实现证书的申请和续期完全自动化
- 开放: 所有软件开源,协议标准化
- 透明: 所有签发的证书记录在公开的 Certificate Transparency(CT)日志中
- 安全: 推动全网 HTTPS 加密
证书类型
| 类型 | 验证级别 | 签发时间 | 有效期 | 说明 |
|---|---|---|---|---|
| DV(Domain Validation) | 域名验证 | 秒级 | 90 天 | Let’s Encrypt 仅签发此类 |
| OV(Organization Validation) | 组织验证 | 数天 | 1-2 年 | 需要商业 CA |
| EV(Extended Validation) | 扩展验证 | 数天 | 1-2 年 | 最高级别,浏览器绿色地址栏 |
注意: Let’s Encrypt 不签发 OV 和 EV 证书。如需组织验证证书,请选择 DigiCert、Sectigo 等商业 CA。
证书有效期
Let’s Encrypt 证书有效期为 90 天。Certbot 默认在到期前 30 天 自动续期。短有效期的设计初衷是:
- 限制密钥泄露的影响范围
- 推动自动化管理,减少人工操作错误
- 加速证书生态系统的更新迭代
1.3 ACME 协议详解
ACME(Automatic Certificate Management Environment)是由 IETF 标准化的协议(RFC 8555),定义了证书颁发机构与客户端之间的自动化通信方式。
ACME 工作流程
┌──────────────┐ ┌──────────────────┐
│ ACME 客户端 │ │ ACME 服务器 (CA) │
│ (Certbot) │ │ (Let's Encrypt) │
└──────┬───────┘ └────────┬─────────┘
│ │
│ 1. 创建账户 (Account Registration) │
│ ───────────────────────────────────> │
│ <─────────────────────────────────── │
│ 返回账户信息 │
│ │
│ 2. 请求证书 (New Order) │
│ ───────────────────────────────────> │
│ <─────────────────────────────────── │
│ 返回验证挑战 │
│ │
│ 3. 完成验证挑战 (Challenge) │
│ ───────────────────────────────────> │
│ <─────────────────────────────────── │
│ 验证结果 │
│ │
│ 4. 提交 CSR (Finalize) │
│ ───────────────────────────────────> │
│ <─────────────────────────────────── │
│ 返回证书 │
│ │
│ 5. 下载证书 │
│ ───────────────────────────────────> │
│ <─────────────────────────────────── │
│ 证书链 │
验证挑战类型
| 挑战类型 | 协议标识 | 验证方式 | 适用场景 |
|---|---|---|---|
| HTTP-01 | http-01 | 在 Web 根目录放置验证文件 | 80 端口可达的标准站点 |
| DNS-01 | dns-01 | 在 DNS 中添加 TXT 记录 | 通配符证书、无法开放 80 端口 |
| TLS-ALPN-01 | tls-alpn-01 | 在 TLS 握手中返回特殊证书 | 仅开放 443 端口的场景 |
HTTP-01 验证流程
1. Certbot 生成验证文件
内容: <token>.<account-key-thumbprint>
2. 放置到 Web 根目录
路径: http://example.com/.well-known/acme-challenge/<token>
3. Let's Encrypt 服务器请求该 URL
GET /.well-known/acme-challenge/<token>
4. 验证文件内容是否匹配
匹配 → 域名验证通过
DNS-01 验证流程
1. Certbot 生成 DNS TXT 记录值
值: <base64url-encoded-SHA256-thumbprint>
2. 添加 DNS TXT 记录
名称: _acme-challenge.example.com
类型: TXT
值: <generated-value>
3. Let's Encrypt 查询 DNS TXT 记录
dig TXT _acme-challenge.example.com
4. 验证记录值是否匹配
匹配 → 域名验证通过
ACME 账户密钥
Certbot 首次运行时会生成一个 ACME 账户密钥(RSA 或 EC),用于:
- 标识客户端身份
- 签署所有 ACME 请求
- 关联已申请的证书
账户密钥存储位置:/etc/letsencrypt/accounts/
1.4 Certbot 工作原理
Certbot 执行证书申请时的具体步骤:
# 1. 检查是否已有账户密钥,没有则创建
# 2. 向 ACME 服务器注册账户
# 3. 提出新证书订单(New Order)
# 4. 服务器返回需要完成的验证挑战
# 5. 根据验证方式(standalone/webroot/dns)完成挑战
# 6. 向 ACME 服务器证明域名控制权
# 7. 生成证书签名请求(CSR)
# 8. 提交 CSR 到 ACME 服务器
# 9. 下载签发的证书
# 10. 将证书保存到本地文件系统
文件存储结构
/etc/letsencrypt/
├── accounts/ # ACME 账户信息
│ └── acme-v02.api.letsencrypt.org/
│ └── directory/
│ └── <account-id>/
│ ├── meta.json
│ ├── private_key.json
│ └── regr.json
├── archive/ # 证书历史文件
│ └── example.com/
│ ├── cert1.pem
│ ├── chain1.pem
│ ├── fullchain1.pem
│ └── privkey1.pem
├── live/ # 当前有效的符号链接
│ └── example.com/
│ ├── cert.pem -> ../../archive/example.com/cert1.pem
│ ├── chain.pem -> ../../archive/example.com/chain1.pem
│ ├── fullchain.pem -> ../../archive/example.com/fullchain1.pem
│ └── privkey.pem -> ../../archive/example.com/privkey1.pem
├── renewal/ # 续期配置
│ └── example.com.conf
└── cli.ini # 全局配置文件
证书文件说明
| 文件 | 内容 | 用途 |
|---|---|---|
cert.pem | 服务器证书 | SSL 配置中的证书文件 |
chain.pem | 中间证书链 | 不含服务器证书的 CA 链 |
fullchain.pem | 完整证书链 | cert.pem + chain.pem,推荐使用 |
privkey.pem | 私钥 | SSL 配置中的私钥文件 |
提示: 配置 Web 服务器时,优先使用
fullchain.pem而非cert.pem,可避免中间证书缺失问题。
1.5 适用场景分析
场景一:个人博客/小型网站
# 最简单的场景:单域名,Nginx 已运行
sudo certbot --nginx -d example.com
特点: 需求简单,HTTP-01 验证即可满足,Certbot 自动配置 Nginx。
场景二:多站点服务器
# 一台服务器上运行多个站点
sudo certbot --nginx -d site1.com -d site2.com -d site3.com
特点: 可以将多个域名合并到一个证书中,减少证书管理开销。
场景三:通配符证书
# 为所有子域名签发一个证书(需 DNS-01 验证)
sudo certbot certonly --manual --preferred-challenges dns \
-d example.com -d "*.example.com"
特点: 必须使用 DNS-01 验证,适合拥有多个子域名的场景。
场景四:Docker 容器环境
# 使用 Docker 运行 Certbot
docker run -it --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/www/certbot:/var/www/certbot \
certbot/certbot certonly --webroot \
-w /var/www/certbot -d example.com
特点: 容器化部署,需要挂载卷存储证书和验证文件。
场景五:反向代理/负载均衡
# 在反向代理层统一处理 SSL
sudo certbot certonly --standalone \
-d api.example.com -d app.example.com
特点: SSL 终止在反向代理层,后端服务无需处理证书。
适用性总结
| 场景 | 推荐验证方式 | 推荐插件 | 复杂度 |
|---|---|---|---|
| 个人博客 | HTTP-01 | nginx/apache | ⭐ |
| 企业官网 | HTTP-01 | nginx/apache | ⭐⭐ |
| 多域名站点 | HTTP-01 | standalone | ⭐⭐ |
| 通配符域名 | DNS-01 | dns-cloudflare | ⭐⭐⭐ |
| Docker 环境 | HTTP-01 | webroot | ⭐⭐⭐ |
| 内网服务 | DNS-01 | 手动/自动化脚本 | ⭐⭐⭐⭐ |
1.6 局限性与替代方案
Let’s Encrypt 的局限
- 仅 DV 证书: 不提供 OV/EV 证书
- 90 天有效期: 需要自动化续期,不适合手动管理
- 速率限制: 每个域名每周 50 个证书,每 IP 每 3 小时 10 个新订单
- 不支持 IP 证书: 必须通过域名访问
- 某些企业场景不适用: 部分金融、政府场景要求 OV/EV 证书
替代方案
| CA/工具 | 类型 | 费用 | 特点 |
|---|---|---|---|
| ZeroSSL | 商业 CA | 免费/付费 | 支持 ACME,90 天免费证书 |
| Buypass | 商业 CA | 免费/付费 | 免费证书有效期 180 天 |
| AWS ACM | 云服务 | 免费(AWS 内) | 自动续期,仅限 AWS 资源 |
| Cloudflare | CDN | 免费/付费 | Universal SSL,边缘证书 |
1.7 速率限制(Rate Limits)
了解 Let’s Encrypt 的速率限制对于生产环境至关重要。
| 限制类型 | 限制值 | 说明 |
|---|---|---|
| 每个注册域名的证书数量 | 每周 50 个 | 如 example.com 下所有子域名 |
| 重复证书 | 每周 5 个 | 完全相同的域名组合 |
| 新订单 | 每 IP 每 3 小时 10 个 | 未注册账户的 IP |
| 验证失败 | 每小时 5 次 | 每个主机名每小时 |
| ACME 账户注册 | 每 IP 每 3 小时 10 个 | 新账户创建 |
查看速率限制
# 使用 Let's Encrypt 的工具查看当前限制
# 访问: https://crt.sh/?q=example.com
# 查看 Certificate Transparency 日志中的证书数量
注意: 开发和测试请使用 staging 环境,避免消耗正式环境的速率限制:
sudo certbot --staging -d example.com
1.8 Staging 环境
使用 staging 环境测试
# 使用 staging 环境申请证书(签发的证书不被浏览器信任)
sudo certbot certonly --standalone --staging \
-d test.example.com
# 查看 staging 环境的证书
sudo certbot certificates --cert-name test.example.com
# 删除 staging 环境的证书
sudo certbot delete --cert-name test.example.com
Staging 与 Production 环境对比
| 特性 | Staging | Production |
|---|---|---|
| ACME 服务器 | acme-staging-v02.api.letsencrypt.org | acme-v02.api.letsencrypt.org |
| 证书信任 | 不受浏览器信任 | 受浏览器信任 |
| 速率限制 | 宽松 | 严格 |
| 适用场景 | 开发测试 | 生产环境 |