Let’s Encrypt 160 小时与 IP 地址证书实战:Certbot 自动续期和监控
更新日期:2026-08-30
Let’s Encrypt 已在 2026 年 1 月正式开放 short-lived certificate 和 IP address certificate。现在可以为公开 IPv4 或 IPv6 地址申请浏览器公开信任的证书,不再必须先准备域名;普通域名也可以主动选择更短的证书生命周期。
这里的“6 天证书”并不是精确 144 小时。Let’s Encrypt 官方定义的有效期是 160 小时,即略多于六天。这个差异会直接影响续期窗口、监控阈值和故障响应,不能只把原来的 90 天 Certbot 任务原样照搬。
本文聚焦 2026 年的新能力。若你需要普通域名证书的入门方法,可以先看本站已有的 Let’s Encrypt 免费 SSL 证书介绍。
先说结论
- short-lived certificate 已 GA,但仍是通过 ACME shortlived profile 主动选择的能力,不是默认值。
- 证书有效期为 160 小时;IP 地址证书强制使用该 short-lived profile。
- IP identifier 支持公开 IPv4 和 IPv6,只能通过 http-01 或 tls-alpn-01 验证,不能用 dns-01。
- Certbot 5.3 加入 --ip-address;使用 webroot 为 IP 签发时,Let’s Encrypt 官方要求 Certbot 5.4 或更高版本。
- 官方 2026 年 3 月指南中,Certbot 可以获取 IP 证书,但 nginx/apache installer 尚不能自动安装它;必须手动配置证书路径和成功续期后的 reload hook。
- 160 小时证书只适合已经实现全自动签发、部署、reload、监控和告警的服务。依靠人工续期会把安全收益变成可用性事故。
短期证书解决了什么问题
传统公开证书在私钥泄露后需要依靠撤销机制缩短风险窗口,但浏览器和客户端对 OCSP、CRL 等撤销信息的处理并不总是可靠。证书生命周期越长,被盗私钥在自然过期前可能被滥用的时间就越长。
160 小时证书通过更频繁地重新验证控制权,把最坏暴露窗口从数月压缩到数天。它还会迫使团队真正自动化 ACME 流程,这通常比“到期前收到邮件再登录服务器操作”更可靠。
短生命周期不代表可以忽略私钥保护或撤销:
- 私钥仍应只允许 root 或 TLS 服务读取,不能进入镜像、Git、日志或工单。
- 发现私钥泄露后仍应撤销并轮换,而不是等待六天自然过期。
- ACME account key、renewal 配置和 deploy hook 同样属于敏感运维资产。
- 监控必须从“30 天内过期”改为按小时观察。
Let’s Encrypt 目前没有把 short-lived profile 设为默认的计划。普通 90 天证书仍可用;官方另有逐步把默认生命周期降到 45 天的长期路线,两件事不要混为一谈。
IP 地址证书适合哪些场景
IP certificate 的 Subject Alternative Name 可以直接包含 IP 地址,客户端通过 HTTPS 直接访问公开 IP 时能够验证证书与目标 IP 是否匹配。
适合考虑的场景包括:
- 没有稳定域名、但有稳定公开 IP 的管理端或设备。
- 云平台中生命周期较短、通过公网 IP 直接建立的后端连接。
- 需要对公开 IP 上的 DoH、API 或临时服务启用公开信任 TLS。
- 同时支持 IPv4 与 IPv6、且客户端确实按 IP 连接的服务。
以下情况通常不适合:
- RFC1918 私网、loopback、链路本地或公网无法访问的地址。
- IP 经常由运营商、NAT、负载均衡或云平台重新分配,但没有释放事件处理。
- CDN 或负载均衡器已经终止 TLS,源站 IP 不直接服务最终客户端。
- 已有稳定域名,域名能提供更清晰的服务身份与迁移能力。
- 无法让 Let’s Encrypt 从公网访问 80 或 443,且没有兼容的验证架构。
IP 证书只证明签发验证时申请方控制该地址,不代表获得了 IP 所有权。释放云公网 IP 后,应立即停止使用对应证书、清理私钥与自动续期,并确认流量不再指向旧资源。
IP 验证为什么不能使用 DNS-01
域名的 dns-01 通过 _acme-challenge TXT 记录证明控制权。IP identifier 本身不是一个普通 DNS name,没有对应的域名 CAA 与 TXT 验证流程,因此 Let’s Encrypt 只允许:
| Challenge | 端口 | IP certificate | 说明 |
|---|---|---|---|
| http-01 | TCP 80 | 支持 | 公开路径返回 ACME token,Certbot webroot 最容易落地 |
| tls-alpn-01 | TCP 443 | 支持 | 需要兼容 ACME 的 TLS termination/client |
| dns-01 | DNS | 不支持 | IP identifier 不通过域名 TXT 记录验证 |
http-01 固定在 80 端口,不能把 ACME server 改到任意高端口。Let’s Encrypt 可能从不同网络位置验证,不要尝试维护一份验证节点 IP allowlist;它会让未来续期随机失败。
签发前检查
1. 确认地址和路由
先由云平台或网络管理员确认目标是当前实例实际控制的公开 IPv4/IPv6,并记录分配资源 ID。不要仅根据第三方“查询我的 IP”页面自动写入生产配置。
在当前 shell 中交互输入经过确认的值:
read -r -p 'Public IP: ' PUBLIC_IP
read -r -p 'ACME webroot: ' WEBROOT
export PUBLIC_IP WEBROOT
: "${PUBLIC_IP:?必须填写实际公开 IP}"
: "${WEBROOT:?必须填写 ACME webroot}"
test -d "$WEBROOT"
WEBROOT 要与 Web Server 为 /.well-known/acme-challenge/ 提供文件的目录一致。命令在变量为空或目录不存在时会停止,避免把占位值继续传给 production ACME。
2. 检查 Certbot 版本与插件
certbot --version
certbot plugins
webroot + IP address 使用 Certbot 5.4+。截至 2026 年 7 月最新 Certbot 是 5.7.0,但发行版仓库版本可能更旧。优先按照 Certbot 官方针对当前系统的安装方式更新,不要把不受维护的随机脚本或 PyPI root 安装混进生产。
3. 验证 HTTP challenge 路径
sudo install -d -m 0755 "$WEBROOT/.well-known/acme-challenge"
printf '%s\n' 'acme-path-ok' | sudo tee "$WEBROOT/.well-known/acme-challenge/health.txt"
curl --fail --show-error "http://${PUBLIC_IP}/.well-known/acme-challenge/health.txt"
IPv6 URL 要使用方括号,例如 http://[IPv6地址]/.well-known/acme-challenge/health.txt。确认公网路径返回预期文本后删除测试文件。若前面有多节点负载均衡,每个可能接收验证请求的节点都必须返回相同 challenge 内容。
先用 staging 签发
Let’s Encrypt 官方给出的 Certbot webroot 路径是:
sudo certbot certonly \
--staging \
--preferred-profile shortlived \
--webroot \
--webroot-path "$WEBROOT" \
--ip-address "$PUBLIC_IP"
--staging 签发的是不被浏览器公开信任的测试证书,用于验证网络、challenge、账户和客户端行为。不要把它配置到正式访问入口后宣称 HTTPS 已上线。
检查 lineage 和 SAN:
sudo certbot certificates
sudo openssl x509 \
-in "/etc/letsencrypt/live/${PUBLIC_IP}/fullchain.pem" \
-noout -issuer -dates -ext subjectAltName
实际 cert name 如果带数字后缀,应以 certbot certificates 输出为准,不能只假定目录一定等于 IP。
staging 全流程成功后,用相同参数去掉 --staging 获取公开信任证书。不要在失败时连续重试 production:先回到 staging 定位端口、Web Server、代理和路径问题。
手动配置 Nginx 或 Apache
Certbot 官方 2026 年 3 月指南明确指出:当时 nginx/apache plugins 尚不能自动安装 IP certificate。Certbot 5.7.0 发布说明也没有宣布这项 installer 能力,因此部署前仍应以本机 certbot plugins 和 staging 结果为准。
Nginx 配置需要指向 Certbot 维护的 live symlink:
ssl_certificate /etc/letsencrypt/live/<CERT_NAME>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<CERT_NAME>/privkey.pem;
把 <CERT_NAME> 替换为 certbot certificates 显示的名称。不要复制某次 archive 下的带序号文件,否则续期产生新文件后 Web Server 仍会加载旧证书。
每次修改先检查再 reload:
sudo nginx -t
sudo systemctl reload nginx
Apache 应使用对应的配置测试与 graceful reload。无论哪种服务器,都不要把 private key 权限改成全局可读来解决启动错误;应修正服务用户、组或受支持的密钥加载方式。
配置只在成功续期后执行的 deploy hook
Certbot 的 deploy-hook 只在成功得到新证书后运行,适合检查配置并 reload:
read -r -p 'Certbot certificate name: ' CERT_NAME
: "${CERT_NAME:?必须填写 certbot certificates 显示的名称}"
sudo certbot reconfigure \
--cert-name "$CERT_NAME" \
--deploy-hook 'nginx -t && systemctl reload nginx' \
--run-deploy-hooks
cert name 必须来自 certbot certificates。reconfigure 会使用 staging test renewal 验证新设置;--run-deploy-hooks 让测试在成功后执行 hook,而且使用当前 active certificate,不会把 staging 临时证书加载到正式服务。部署 Apache、HAProxy 或其他代理时替换为该服务的安全配置检查与 reload 命令。hook 通常以 root 权限运行,只能调用 root 拥有、不可被普通用户修改的固定脚本,不能拼接请求参数或外部内容。
然后验证续期链路:
sudo certbot renew --dry-run --run-deploy-hooks
普通 dry-run 默认不会运行 deploy hook,因此这里显式加入 --run-deploy-hooks。测试必须覆盖 challenge、签发模拟与 deploy hook;只有真实续期才会保存新证书。仅运行 certbot renew 并看到“not yet due”不能证明未来 reload 会成功。
续期频率与 systemd timer
Certbot 4.0 起在剩余生命周期小于 1/3 时认为证书进入续期窗口。对 160 小时证书,约为剩余 53 小时。建议续期调度至少每 12 小时运行一次,让 transient network failure 仍有多次恢复机会。
检查当前安装方式提供的 timer:
systemctl list-timers --all | grep -i certbot
systemctl status certbot.timer
Snap 或发行版可能使用不同 unit 名称;以 list-timers 输出为准。不要同时启用 cron、systemd 和容器定时器,让多个进程争抢 renewal lock。
监控不应只看本地文件日期
至少建立三层监控:
- 外部 TLS 探测: 从用户路径连接公开 IP,验证 SAN、信任链和剩余小时。
- Certbot 任务: 记录 timer 最后成功时间、renew exit code、ACME error type。
- 部署状态: 比较磁盘 live certificate serial 与 Web Server 实际提供的 serial,发现“续期成功但未 reload”。
建议告警阈值按小时设置,例如剩余 72 小时 warning、48 小时 critical,并根据实际续期窗口与值班响应时间调整。160 小时证书如果仍沿用“剩余 15 天报警”,监控永远不会在有效时间内触发。
还要监控:
- TCP 80/443 从公网是否可达。
- /.well-known/acme-challenge/ 是否被 WAF、redirect 或认证页面拦截。
- ACME account/renewal 目录是否持久化。
- deploy hook 是否通过配置测试并成功 reload。
- 云 IP 是否发生解绑、漂移或实例销毁。
Rate limit 与重试策略
Let’s Encrypt 生产环境存在 new order、相同 identifier set 和 registered domain/IP 等限制。2026 年 8 月文档列出的关键边界包括:相同 identifier set 每 7 天最多 5 张新证书;单 IPv4 或 IPv6 /64 的 registered-domain 口径每 7 天最多 50 张。
正常 renewal 在保持 lineage、account 和 identifier set 的情况下通常不会像新签发一样消耗限额,支持 ARI 的客户端还能更准确表达替换关系。常见事故反而来自:
- 每次容器启动都删除 /etc/letsencrypt 并重新注册、签发。
- CI 失败后无退避地循环请求 production。
- 测试阶段不用 staging。
- 修改 identifier set 以绕过错误,而没有解决 challenge 根因。
遇到 rate-limit response 应尊重 Retry-After,不要继续并发重试。撤销证书不会返还已经消耗的签发容量。
IPv6、Anycast 与多节点注意事项
IPv6 证书本身受支持,但验证与服务路径必须都能从公网正确到达。防火墙只开放 IPv4、AAAA/路由不一致、Web Server 只监听单栈,都会导致续期失败。
Anycast 或负载均衡场景中,Let’s Encrypt 的多点验证可能到达不同节点。应把 challenge token 放在共享存储、由统一控制面分发,或使用明确支持该拓扑的 ACME client。不要靠“这次验证碰巧到了正确节点”判断自动续期可靠。
回滚与故障处理
短期证书没有足够时间让团队慢慢排查。上线前保留:
- 上一张仍有效证书及其私钥的受控备份。
- Web Server 配置的版本记录与可验证 rollback。
- staging 验证命令、生产签发命令和 deploy hook 日志。
- 云 IP 资源 ID、路由和防火墙变更记录。
如果新证书导致 Web Server 无法 reload,应保留当前运行进程,先修复配置,不要删除 /etc/letsencrypt/live symlink 或 archive。若 challenge 连续失败,优先恢复 80/443 路径和 renewal state;不要通过反复创建新 account/lineage 消耗 production 配额。
上线检查清单
- 目标是当前服务实际控制、可公网路由的 IPv4/IPv6。
- Certbot 为 5.4+,当前插件与 profile 支持经过 staging 验证。
- http-01 的 80 端口或 tls-alpn-01 的 443 路径可从公网访问。
- production certificate 的 SAN、issuer、160 小时有效期和信任链正确。
- Web Server 使用 live/<CERT_NAME> 路径,不引用 archive 序号文件。
- deploy hook 只在成功续期后执行,并先 config test 再 reload。
- certbot renew --dry-run 全链路通过。
- 定时任务至少每 12 小时运行且不存在重复 scheduler。
- 外部证书、renew job、reload 和 IP 生命周期均有按小时告警。
- staging 与 production 状态分离,失败重试遵守 Retry-After。


