SSL 证书有效期要缩到 47 天了!用 ACME 协议 + Certbot 在亚马逊云科技 EC2 上实现自动续期全攻略
CA/Browser Forum 去年通过了一个让运维集体头疼的决议:SSL/TLS 证书有效期要分阶段缩短,到 2029 年只剩 47 天。意味着一年要续 8 次以上,手动操作直接不可能了。这篇文章手把手教你在亚马逊云科技 EC2 + Nginx 环境下用 ACME 协议搞定自动续期,顺便对比一下 ACM 托管方案。
先说背景:为什么证书有效期越来越短
CA/Browser Forum 在 2025 年 4 月通过了正式决议,时间表长这样:
| 时间节点 | 证书有效期上限 | 域名验证复用期 |
|---|---|---|
| 现在 | 398 天 | 398 天 |
| 2026 年 3 月 15 日 | 200 天 | 200 天 |
| 2027 年 3 月 | 100 天 | 100 天 |
| 2029 年 3 月 | 47 天 | ~10 天 |
47 天是怎么算的:31 天(覆盖大月)+ 15 天缓冲 + 1 天冗余。
缩短有效期的核心目的就三个:
- 确保证书信息跟实际情况一致
- 缩小证书被盗用或错发的风险窗口
- 倒逼全行业搞自动化
说白了,以后不搞自动化就等着半夜被告警叫醒吧。
两条路线:ACM 托管 vs 自建 ACME
路线一:亚马逊云科技 ACM(省心方案)
如果你的架构用了 ALB / CloudFront / API Gateway 这些亚马逊云科技托管服务,直接用 ACM(Amazon Certificate Manager)申请证书就行。ACM 的证书到期自动续期,不需要你操心。零配置、零运维。
适合:前面挂了负载均衡器或 CDN 的架构。
路线二:EC2 自建 Nginx(本文重点)
但现实是,很多团队出于各种原因(历史架构、特殊合规要求、第三方证书),直接在 EC2 上跑 Nginx 并用第三方证书。这种情况下证书管理就是你自己的事。
这篇文章就是为这种场景写的。
环境准备
- Amazon Linux 2023(AL2、Ubuntu、RHEL 命令类似)
- Nginx 已安装并运行
- 域名 DNS A 记录指向 EC2 公网 IP
- 安全组放行 80(HTTP)和 443(HTTPS)
安装 Nginx
# Amazon Linux 2023sudodnfinstallnginx-ysudosystemctlenablenginxsudosystemctl start nginx安装 Certbot
# pip 方式sudopip3installcertbot certbot-nginx# 或 dnf 方式sudodnfinstallcertbot python3-certbot-nginx-y基础 Nginx 配置
编辑/etc/nginx/conf.d/yourdomain.conf:
server { listen 80; server_name yourdomain.com; location / { root /usr/share/nginx/html; index index.html; } }验证:
sudonginx-tsudosystemctl reload nginxcurlhttp://yourdomain.com# 应该返回你的页面Certbot 三种模式详解
模式一:Standalone — 简单但有短暂停机
原理:Certbot 在本地 80 端口起一个临时 Web 服务器处理 ACME HTTP-01 验证。因为 Nginx 占着 80 端口,必须先停 Nginx。
# 停 Nginx 释放 80 端口sudosystemctl stop nginx# 申请证书sudocertbot certonly--standalone-dyourdomain.com# 重启 Nginxsudosystemctl start nginx拿到证书后配置 HTTPS:
server { listen 80; server_name yourdomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { root /usr/share/nginx/html; index index.html; } }自动续期带钩子:
sudocertbot renew --dry-run\--pre-hook"systemctl stop nginx"\--post-hook"systemctl start nginx"踩坑提醒:每次续期有 10-30 秒停机,Nginx 被停掉了。适合开发测试环境,生产慎用。
模式二:Webroot — 零停机
原理:Certbot 把验证文件放到 Nginx 的 Web 根目录,Nginx 直接提供文件,不需要停服务。
关键一步:在 Nginx 配置里给 ACME 验证路径开个口子,不要被 301 重定向吃掉。
server { listen 80; server_name yourdomain.com; # ACME 验证直接走,不重定向 location /.well-known/acme-challenge/ { root /usr/share/nginx/html; } # 其他请求重定向 HTTPS location / { return 301 https://$host$request_uri; } }我之前踩过一个坑:忘了加这个 location 块,80 端口全部 301 到 HTTPS,结果 Let’s Encrypt 的验证请求也被重定向了,签发直接失败。排查了半小时才想起来。
验证路径是否可访问:
sudomkdir-p/usr/share/nginx/html/.well-known/acme-challengeecho"test"|sudotee/usr/share/nginx/html/.well-known/acme-challenge/test-token# 应返回 200,不是 301curl-Ihttp://yourdomain.com/.well-known/acme-challenge/test-tokensudorm/usr/share/nginx/html/.well-known/acme-challenge/test-token申请证书:
sudocertbot certonly--webroot\-w/usr/share/nginx/html\-dyourdomain.com续期不需要钩子,Nginx 全程运行:
sudocertbot renew --dry-run小贴士:加个 deploy 钩子在续期后自动 reload Nginx 加载新证书:
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh#!/bin/bashsystemctl reload nginx模式三:Nginx 插件 — 零停机 + 全自动
原理:Certbot 直接跟 Nginx 对话,临时改 Nginx 配置处理验证,完成后自动装证书并 reload,全程不用你管。
# 一条命令搞定sudocertbot--nginx-dyourdomain.com这条命令一次完成四件事:
- 通过 Nginx 处理 ACME 验证
- 下载证书
- 自动更新 Nginx 配置(添加 ssl 指令)
- reload Nginx
续期同样简单:
sudocertbot renew --dry-run我的建议:大部分生产环境用这个模式就行。除非你对 Nginx 配置有洁癖不想让 Certbot 碰。
三种模式对比
| 特性 | Standalone | Webroot | Nginx 插件 |
|---|---|---|---|
| 续期停机 | ⚠️ 10-30s | ✅ 零 | ✅ 零 |
| 停 Nginx | 是 | 否 | 否 |
| 改 Nginx 配置 | 不需要 | 需要(加 ACME location) | 不需要(自动管理) |
| 自动配置 SSL | 否 | 否 | 是 |
| 复杂度 | 低 | 中 | 低 |
| 适合场景 | 开发测试 | 需要完全掌控配置 | 大部分生产环境 |
配置自动续期定时任务
大多数系统安装 Certbot 时会自动创建 systemd 定时器或 cron。确认一下:
# 检查 systemd 定时器sudosystemctl list-timers|grepcertbot# 或检查 cronsudocat/etc/cron.d/certbot2>/dev/null如果都没有,手动加:
# 每天跑两次(Certbot 只在到期前 30 天内才真正续期)echo"0 3,15 * * * root certbot renew --quiet"|sudotee/etc/cron.d/certbot测试:
sudocertbot renew --dry-run# 应看到:The dry run was successful.注意:用 Standalone 模式的话,cron 里必须带--pre-hook和--post-hook,不然 Certbot 会因为 80 端口被占用而失败。
DigiCert 商业证书也能用 ACME
Let’s Encrypt 是免费的,但如果你用的是 DigiCert 这种商业 CA,一样能通过 ACME 协议自动续期。
前置条件
- DigiCert CertCentral 账户
- ACME 目录 URL(Settings → ACME Directory URLs)
- EAB 密钥对:KID + HMAC Key
注册
sudocertbot register\--server"https://acme.digicert.com/v2/acme/directory/"\--eab-kid"YOUR_EAB_KID"\--eab-hmac-key"YOUR_EAB_HMAC_KEY"\--emailadmin@yourdomain.com\--agree-tos获取证书(三种模式都行)
# Nginx 插件模式sudocertbot--nginx\--server"https://acme.digicert.com/v2/acme/directory/"\-dyourdomain.com后续续期跟 Let’s Encrypt 完全一样,certbot renew会自动用 DigiCert 的 ACME 服务器。
实战建议
- 能用 ACM 就用 ACM:如果架构允许(ALB/CloudFront/API Gateway),证书管理这种事没必要自己折腾
- 不得不自建就用 Nginx 插件模式:一条命令搞定,后续零维护
- 监控别忘了:加个 CloudWatch 自定义指标监控证书到期时间,提前告警
- 测试环境先跑一遍:别直接在生产上搞。
--dry-run是你的好朋友 - 备份私钥:
/etc/letsencrypt/目录定期备份,实例挂了还能恢复
写在后面
证书有效期缩短这事已经板上钉钉了。2026 年 3 月开始 200 天,2027 年 100 天,2029 年 47 天——越往后越紧迫。趁现在还有缓冲期把自动化搞起来,别等到 47 天的时候手忙脚乱。
如果你在亚马逊云科技上跑服务,ACM 是省心方案;如果必须自建,Certbot + ACME 协议就是标准答案。本文所有操作均在 Amazon Linux 2023 + Nginx 1.28 + Certbot 2.6 上实测验证过。
参考资料:
- 应对TLS/SSL证书有效期大幅缩短——使用ACME协议实现证书自动续期
- Amazon Certificate Manager
- Amazon EC2