简短回答:CA/Browser Forum 于2025年4月11日通过的 SC-081 提案,分三步缩短公开受信任 TLS 证书的最长有效期:2026年3月15日起签发的证书有效期最长 200 天,2027年3月15日起最长 100 天,2029年3月15日起最长 47 天。CA 可以复用域名验证结果的时长也在同样的日期缩短:先是 200 天,然后是 100 天,最后是 10 天。实际上,每张证书都必须通过自动化手段(ACME)签发和部署。续期应遵循 CA 给出的 ARI 窗口;你还需要监控,在续期出故障而仍有时间修复时及时告警。私有 CA 不受影响。
时间表
这些规则见《基线要求》(Baseline Requirements,2.3.1 版,2026年10月)的第 6.3.2 节和第 4.2.1 节。SC-081v3 提案由 Apple 提出,Sectigo、Google Chrome 和 Mozilla 附议。该提案以 25 家 CA 赞成、无反对、5 家弃权获得通过,四家浏览器厂商全部投了赞成票。
| 证书签发日期 | 最长有效期 | 域名/IP 验证复用期 | 组织身份信息复用期 |
|---|---|---|---|
| 2026年3月15日之前 | 398 天 | 398 天 | 825 天 |
| 2026年3月15日至2027年3月14日 | 200 天 | 200 天 | 398 天 |
| 2027年3月15日至2029年3月14日 | 100 天 | 100 天 | 398 天 |
| 2029年3月15日起 | 47 天 | 10 天 | 398 天 |
按这些数字做规划时,有几个细节需要注意:
- 这些数字是上限,由 CA 在签发时执行。2026年3月14日签发的证书仍然可以有效 398 天。没有任何规定强制你在它过期前更换,但它的替换证书有效期会很短。
- “有效期”的首尾两端都计算在内。《基线要求》把有效期定义为从
notBefore到notAfter(含两端)的时间段,并建议留出一天余量:证书有效期“不应(SHOULD NOT)”超过 199 天、99 天和 46 天。 - 验证结果复用期限的变化更大。如今,CA 可以在几个月内一直复用“你控制着
example.com”这一证明。2029年起,这份证明最多只能是 10 天前取得的,因此几乎每次签发都需要重新进行域名验证,DNS 或 HTTP 挑战也必须自动化。 - OV 和 EV 证书中的组织详细信息(公司名称、地址)可以复用 398 天,而不再是 825 天。
- 适用范围:《基线要求》约束的是公开受信任 CA 签发的 TLS 服务器证书。你自己的内部 CA 签发的证书、客户端证书和 S/MIME 证书适用其他规则,或者不受任何规则约束。
CA 目前签发的证书
2026年10月20日,几个大型网站提供的证书情况如下。输出来自监控一节中的 lifetimes.sh 脚本:
letsencrypt.org Let's Encrypt 2026-09-04 -> 2026-12-03 (90 days)
www.google.com Google Trust Services 2026-09-28 -> 2026-12-21 (84 days)
github.com Sectigo Limited 2026-09-01 -> 2026-11-29 (90 days)
www.microsoft.com Microsoft Corporation 2026-01-22 -> 2027-01-17 (360 days)
www.amazon.com Amazon 2026-01-19 -> 2027-01-11 (358 days)
www.digicert.com DigiCert Inc 2026-10-11 -> 2026-11-26 (47 days)
其中两个网站仍在使用有效期接近一年的证书,它们签发于2026年1月,恰好在 200 天上限生效之前。DigiCert 已经在自己的网站上使用 47 天证书。Let's Encrypt 公布的计划比《基线要求》的要求推进得更快:
- 2026年5月13日:需主动选用的
tlsserver配置文件(profile)签发 45 天证书。 - 2027年2月10日:默认的
classic配置文件签发 64 天证书,授权复用期为 10 天。 - 2028年2月16日:
classic签发 45 天证书,授权复用期为 7 小时。
线上的 ACME 目录列出了目前可以申请的配置文件:
"meta": {
"profiles": {
"classic": "https://letsencrypt.org/docs/profiles#classic",
"shortlived": "https://letsencrypt.org/docs/profiles#shortlived",
"tlsserver": "https://letsencrypt.org/docs/profiles#tlsserver"
}
},
"renewalInfo": "https://acme-v02.api.letsencrypt.org/acme/renewal-info"
需要自动化的环节
证书有效期为 398 天时,每年手动续期一次虽然麻烦,但还能应付。到了 47 天的有效期和 10 天的验证复用期,手动续期就成了每个域名每年至少 8 次、容易出错的工作;如果在有效期过去三分之二时续期,则接近 12 次。这些工作可以分为四部分。
1. 通过 ACME 签发。来自公共 CA 的每一张证书都应使用 ACME 客户端(RFC 8555)申请。大多数商业 CA 也提供 ACME 端点,通常需要配合外部账户绑定使用。如果某张证书仍然通过电子邮件、门户网站下载或工单获取,应把它排在改造清单的首位。
2. 无人值守的验证。选择无需人工参与的挑战方式:
http-01要求为该域名提供服务的每台主机都能通过 80 端口访问。dns-01需要通过 API 访问你的 DNS 服务商。在服务商允许的情况下,把令牌的权限范围限定在_acme-challenge记录上。tls-alpn-01完全在 443 端口上完成。
有两种较新的验证方法正是为这种情况设计的。《基线要求》§3.2.2.4.21 中的“DNS Labeled with Account ID”(即 ACME 的 dns-account-01 挑战)让多个 ACME 账户可以验证同一个域名,而不必争用同一条 _acme-challenge 记录。“DNS TXT Record with Persistent Value”(§3.2.2.4.22,SC-088 提案)让你只需发布一次长期保留的记录:
_validation-persist.example.com IN TXT "authority.example; accounturi=https://authority.example/acct/123; persistUntil=1782424856"
CA 对这条记录的每次检查,最多只能当作 10 天内有效的验证结果。不过 CA 会自行重新检查这条记录,所以每次续期都无需有人改动 DNS。依赖这种方法之前,先向你的 CA 确认它是否支持。
3. 跟随 CA 安排的续期。提前续期,让 CA 来调整续期时间:
- 在有效期过去约三分之二时续期。对于 45 天证书,就是第 30 天。Let's Encrypt 明确表示:“按硬编码的 60 天间隔续期将不再够用。”certbot 从 4.0 版起改为在剩余三分之一有效期时续期,而不再固定在剩余 30 天时续期。
- 使用 ARI(RFC 9773),详见下一节。CA 会告诉每个客户端何时续期;需要批量吊销证书时,CA 还可以把这个窗口提前。
- 如果希望在 CA 更改默认设置之前就用上 45 天证书,就显式请求相应的配置文件。
4. 部署到每一份副本。更新磁盘上的文件并不意味着结束。列出证书被复制到的每一个位置:
- 需要上传证书的负载均衡器和 CDN
- Kubernetes Secret
- Java 密钥库和 PKCS#12 证书包
- 专用设备、邮件服务器、数据库和消息代理
- 固定了叶子证书的移动应用
每一份副本都需要重载钩子,或者能获取新证书的集成。按这样的频率,在应用中固定叶子证书或其密钥已经行不通。应改为固定 CA 密钥;更好的做法是不做固定。
下面的测试用 certbot 5.8.0 连接本地的 Pebble 2.10.1 ACME 服务器,该服务器的 tlsserver 配置文件签发 45 天证书。测试表明,配置文件请求和续期配置都按文档所述工作:
$ certbot certonly --standalone --non-interactive --agree-tos --register-unsafely-without-email \
--server https://localhost:14000/dir -d app.example.test --preferred-profile tlsserver
Account registered.
Requesting a certificate for app.example.test
Successfully received certificate.
This certificate expires on 2026-12-04.
$ openssl x509 -in /etc/letsencrypt/live/app.example.test/cert.pem -noout -startdate -enddate
notBefore=Oct 20 11:47:52 2026 GMT
notAfter=Dec 4 11:47:51 2026 GMT
$ grep -E "preferred_profile|server" /etc/letsencrypt/renewal/app.example.test.conf
preferred_profile = tlsserver
server = https://localhost:14000/dir
$ certbot renew --non-interactive
Processing /etc/letsencrypt/renewal/app.example.test.conf
Certificate not yet due for renewal
certbot 会把配置文件记录在续期配置中,因此之后的每次续期都会再次请求它。--preferred-profile 选项从 certbot 4.0 起提供。如果 CA 的目录没有列出所指定的配置文件,certbot 会退回使用 CA 的默认配置文件;--required-profile 则会让签发或续期直接失败。配置文件机制出自 draft-ietf-acme-profiles,该草案在2026年10月正等待 IESG 评审。certbot 以外的客户端有各自的选项名称。
ACME 续期信息(ARI)
ARI(RFC 9773,2025年6月)把续期时间从客户端的猜测变成了向 CA 提出的询问。客户端为每张证书用其颁发机构密钥标识符(Authority Key Identifier)和序列号构造一个标识符:
url = renewalInfo || '/' || base64url(AKI keyIdentifier) || '.' || base64url(Serial)
然后,客户端无需身份验证即可轮询该 URL。响应中包含 suggestedWindow,Retry-After 响应头说明何时再次查询。你可以手动查询任意一张 Let's Encrypt 证书的续期信息:
#!/bin/bash
set -e
host="$1"
openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null | openssl x509 -out cert.pem
aki=$(openssl x509 -in cert.pem -noout -ext authorityKeyIdentifier | grep -o -E '([0-9A-F]{2}:){19}[0-9A-F]{2}' | tr -d ':')
serial=$(openssl x509 -in cert.pem -noout -serial | cut -d= -f2)
# The DER INTEGER content keeps a leading 00 byte when the high bit is set.
[ $(( 16#${serial:0:1} )) -ge 8 ] && serial="00$serial"
b64url() { python3 -c 'import sys,base64; print(base64.urlsafe_b64encode(bytes.fromhex(sys.stdin.read().strip())).decode().rstrip("="))'; }
id="$(printf %s "$aki" | b64url).$(printf %s "$serial" | b64url)"
ari=$(curl -s https://acme-v02.api.letsencrypt.org/directory | grep -o '"renewalInfo": *"[^"]*"' | cut -d'"' -f4)
openssl x509 -in cert.pem -noout -issuer -startdate -enddate
echo "GET $ari/$id"
curl -s -D - "$ari/$id" | grep -i -E '^retry-after|^\{|"'
issuer=C=US, O=Let's Encrypt, CN=YE2
notBefore=Sep 4 14:34:32 2026 GMT
notAfter=Dec 3 14:34:31 2026 GMT
GET https://acme-v02.api.letsencrypt.org/acme/renewal-info/uVnyjs8i8IbTN0j_dhQYuoLYVYc.BUOTO-OGs6KzrdU08hA7yLZf
retry-after: 25769
{
"suggestedWindow": {
"start": "2026-11-02T17:18:36Z",
"end": "2026-11-04T12:29:25Z"
这张证书的有效期为 90 天,窗口在签发 59 天后打开,大约在有效期的三分之二处。客户端应在窗口内随机选择一个时刻,让续期在时间上分散开。如果 CA 需要批量吊销证书,它会把窗口移到过去,行为规范的客户端就会在几小时内续期,而不是等到证书过期时才出故障。续期时,客户端会在新订单的 replaces 字段中发送旧证书的标识符。
常用客户端对 ARI 的支持情况,摘自各自的版本说明:
| 客户端 | 支持 ARI 的版本 | 说明 |
|---|---|---|
| certbot | 4.1.0(2025年6月) | certbot renew 中默认启用。5.0 版会在多次运行之间保存 Retry-After |
| Caddy | 2.8.0(2024年5月) | 通过 CertMagic 内置 |
| lego | 4.12.0(2023年5月) | 最早的实现。标识符格式随草案的变化做过更新 |
| acme.sh | 3.1.4(2026年7月) | 默认启用。NO_ARI=1 可将其禁用。cron 任务现在每 6 小时运行一次 |
| cert-manager | 1.21.0(2026年7月) | 实验性功能,需开启 ACMEUseARI 特性门控 |
能发现续期故障的监控
自动化出故障时往往悄无声息:DNS API 令牌过期了,防火墙变更封锁了 80 端口,重载钩子不再生效。对于在第 30 天续期的 47 天证书,从第一次续期失败到服务中断,大约只有 17 天。要在这段时间的早期发出告警。
从外部检测:探测每一个公开域名,而不只是你记得的那些。Prometheus 的 blackbox exporter 以 probe_ssl_earliest_cert_expiry 指标暴露所提供证书链的过期时间:
probe_ssl_earliest_cert_expiry 1.795737599e+09
probe_success 1
probe_tls_version_info{version="TLS 1.3"} 1
下面两条告警规则通过了 promtool check rules 检查(Prometheus 3.5.0)。第一条在续期逾期时触发,第二条在即将发生服务中断时触发:
groups:
- name: certificates
rules:
- alert: CertificateRenewalOverdue
# Fires when less than a third of a 47-day lifetime (about 16 days) is left:
# the renewal job should have replaced the certificate by now.
expr: probe_ssl_earliest_cert_expiry - time() < 16 * 86400
for: 1h
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }}: certificate expires in {{ $value | humanizeDuration }}"
- alert: CertificateExpiresSoon
expr: probe_ssl_earliest_cert_expiry - time() < 7 * 86400
for: 10m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }}: certificate expires in {{ $value | humanizeDuration }}"
用脚本检测:如果证书在 N 秒内过期,openssl x509 -checkend N 会以退出状态 1 退出,这足以用于 cron 任务或 CI 步骤:
$ openssl x509 -in cert.pem -noout -enddate
notAfter=Nov 26 23:59:59 2026 GMT
$ openssl x509 -in cert.pem -noout -checkend $((30 * 86400)); echo "exit status: $?"
Certificate will not expire
exit status: 0
$ openssl x509 -in cert.pem -noout -checkend $((45 * 86400)); echo "exit status: $?"
Certificate will expire
exit status: 1
本页前面的统计表就出自这个脚本:
#!/bin/bash
for host in "$@"; do
openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null | openssl x509 -out /tmp/c.pem 2>/dev/null || { echo "$host: no certificate"; continue; }
nb=$(openssl x509 -in /tmp/c.pem -noout -startdate | cut -d= -f2)
na=$(openssl x509 -in /tmp/c.pem -noout -enddate | cut -d= -f2)
issuer=$(openssl x509 -in /tmp/c.pem -noout -issuer -nameopt multiline | grep -E "organizationName" | head -1 | cut -d= -f2 | sed 's/^ *//')
days=$(( ($(date -d "$na" +%s) - $(date -d "$nb" +%s) + 1) / 86400 ))
printf '%-22s %-26s %s -> %s (%s days)\n' "$host" "$issuer" "$(date -u -d "$nb" +%F)" "$(date -u -d "$na" +%F)" "$days"
done
从 CA 一侧检测:证书透明度(CT)日志记录了为你的域名签发的每一张证书。CT 监控能显示已经完成的续期,以及你意料之外的证书。参见面向开发者的证书透明度,或者用 CT 历史查询工具查看某个域名的证书历史。要了解一组域名准备得如何,证书有效期计算器会按时间表逐一推算你的每张证书。
CAA 与账户绑定
验证结果复用期缩短意味着验证次数增多,而每次验证都会检查你的 CAA 记录。自2027年3月15日起(SC-098 提案),CA 还必须遵守 RFC 8657 中的 accounturi 和 validationmethods 参数。借助它们,你可以把证书签发限定在你自己的 ACME 账户和你选定的挑战类型上:
example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789; validationmethods=dns-01"
CAA 记录生成器可以生成这类记录。注意,过时的 CAA 记录会阻止你自己的续期,而续期现在每年至少要进行 8 次,不再是一年一次。
常见错误
- 固定的续期间隔。“每 60 天续期一次”对 45 天证书来说已经行不通。应按有效期的一定比例续期,或按 ARI 续期。
- 续期后不重新加载。新文件已经在磁盘上,服务器却仍从内存中提供旧证书,直到它过期。要测试部署钩子,而不只是测试续期。
- 忘记副本。源站会自动续期,但 CDN 或负载均衡器上仍是手动上传的证书。
- 过期前 7 天才告警。对于 47 天证书,过期前一周才告警,根本没有时间排查 DNS API 或防火墙问题。应在续期逾期时就告警。
- 在移动应用或 API 客户端中固定叶子密钥。每次换用新密钥的续期都会让它们无法正常工作。
- 以为私有 PKI 也必须跟进。你的内部 CA 可以保留自己的策略。短有效期在那里同样是个好主意,但采用与否由你决定。
参考资料
- CA/Browser Forum,《基线要求》 v2.3.1:§1.2.2(相关日期)、§3.2.2.4.21–22(新的 DNS 方法)、§4.2.1(复用期限)、§6.3.2(有效期)。
- SC-081v3 提案(2025年4月11日通过,2025年5月16日生效)。
- RFC 9773:ACME 续期信息。RFC 8555:ACME。draft-ietf-acme-profiles。
- Let's Encrypt,把证书有效期缩短到 45 天和配置文件。
- certbot、Caddy、lego、acme.sh 和 cert-manager 的版本说明。
- RFC 8659(CAA)和 RFC 8657(CAA 的
accounturi和validationmethods参数)。
文中的命令输出于2026年10月20日生成,所用环境为 node:24.22.0-trixie(OpenSSL 3.5.7、curl 8.14.1)、certbot/certbot:v5.8.0 配合 ghcr.io/letsencrypt/pebble:2.10.1、quay.io/prometheus/blackbox-exporter:v0.25.0 以及 prom/prometheus:v3.5.0。