SSL 证书有效期要缩到 47 天了!用 ACME 协议 + Certbot 在亚马逊云科技 EC2 上实现自动续期全攻略
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 2023
sudo dnf install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
安装 Certbot
# pip 方式
sudo pip3 install certbot certbot-nginx
# 或 dnf 方式
sudo dnf install certbot 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;
}
}
验证:
sudo nginx -t
sudo systemctl reload nginx
curl http://yourdomain.com # 应该返回你的页面
Certbot 三种模式详解
模式一:Standalone — 简单但有短暂停机
原理:Certbot 在本地 80 端口起一个临时 Web 服务器处理 ACME HTTP-01 验证。因为 Nginx 占着 80 端口,必须先停 Nginx。
# 停 Nginx 释放 80 端口
sudo systemctl stop nginx
# 申请证书
sudo certbot certonly --standalone -d yourdomain.com
# 重启 Nginx
sudo systemctl 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;
}
}
自动续期带钩子:
sudo certbot 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 的验证请求也被重定向了,签发直接失败。排查了半小时才想起来。
验证路径是否可访问:
sudo mkdir -p /usr/share/nginx/html/.well-known/acme-challenge
echo "test" | sudo tee /usr/share/nginx/html/.well-known/acme-challenge/test-token
# 应返回 200,不是 301
curl -I http://yourdomain.com/.well-known/acme-challenge/test-token
sudo rm /usr/share/nginx/html/.well-known/acme-challenge/test-token
申请证书:
sudo certbot certonly --webroot \
-w /usr/share/nginx/html \
-d yourdomain.com
续期不需要钩子,Nginx 全程运行:
sudo certbot renew --dry-run
小贴士:加个 deploy 钩子在续期后自动 reload Nginx 加载新证书:
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
模式三:Nginx 插件 — 零停机 + 全自动
原理:Certbot 直接跟 Nginx 对话,临时改 Nginx 配置处理验证,完成后自动装证书并 reload,全程不用你管。
# 一条命令搞定
sudo certbot --nginx -d yourdomain.com
这条命令一次完成四件事:
- 通过 Nginx 处理 ACME 验证
- 下载证书
- 自动更新 Nginx 配置(添加 ssl 指令)
- reload Nginx
续期同样简单:
sudo certbot renew --dry-run
我的建议:大部分生产环境用这个模式就行。除非你对 Nginx 配置有洁癖不想让 Certbot 碰。
三种模式对比
| 特性 | Standalone | Webroot | Nginx 插件 |
|---|---|---|---|
| 续期停机 | ⚠️ 10-30s | ✅ 零 | ✅ 零 |
| 停 Nginx | 是 | 否 | 否 |
| 改 Nginx 配置 | 不需要 | 需要(加 ACME location) | 不需要(自动管理) |
| 自动配置 SSL | 否 | 否 | 是 |
| 复杂度 | 低 | 中 | 低 |
| 适合场景 | 开发测试 | 需要完全掌控配置 | 大部分生产环境 |
配置自动续期定时任务
大多数系统安装 Certbot 时会自动创建 systemd 定时器或 cron。确认一下:
# 检查 systemd 定时器
sudo systemctl list-timers | grep certbot
# 或检查 cron
sudo cat /etc/cron.d/certbot 2>/dev/null
如果都没有,手动加:
# 每天跑两次(Certbot 只在到期前 30 天内才真正续期)
echo "0 3,15 * * * root certbot renew --quiet" | sudo tee /etc/cron.d/certbot
测试:
sudo certbot 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
注册
sudo certbot register \
--server "https://acme.digicert.com/v2/acme/directory/" \
--eab-kid "YOUR_EAB_KID" \
--eab-hmac-key "YOUR_EAB_HMAC_KEY" \
--email admin@yourdomain.com \
--agree-tos
获取证书(三种模式都行)
# Nginx 插件模式
sudo certbot --nginx \
--server "https://acme.digicert.com/v2/acme/directory/" \
-d yourdomain.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 上实测验证过。
参考资料:
更多推荐
所有评论(0)