⭐ 推荐:社区规则条款 V1.0

SSL证书被吊销后网站会怎样,如何避免误吊销?

四大皆空
四大皆空 正式会员萌新站长
发布于 2026-10-28 00:46 ·7 浏览 ·12 回复
内容摘要

证书被吊销后,普通吊销多导致部分客户端和接口静默失败,keyCompromise 则触发浏览器硬拦截使全站 HTTPS 失效;避免误吊销需私钥不外泄、用 CAA 锁定签发 CA、监控 CT 日志并规范 DCV 与证书信息。

结论:证书被吊销后,桌面 Chrome、Firefox 由于采用“软失败”处理,多数用户可能察觉不到,但 Safari、部分 Android 客户端、Java/.NET 服务端调用以及 App 内置的 HTTPS 校验会直接握手失败;一旦吊销原因是 keyCompromise(私钥泄露),证书会被写入浏览器厂商的硬拦截列表,等于站点对所有用户“强制下线”。避免误吊销的关键只有三件事:私钥不出服务器、用 CAA 记录锁定可签发的 CA、持续监控 CT 日志。

证书被吊销后,网站具体会出现什么现象?

**吊销的影响取决于吊销原因和客户端,不是“全都打不开”,但最容易出事的是接口和移动端。**浏览器对 CRL(证书吊销列表)和 OCSP(在线证书状态协议)多采用 soft-fail:查询不到状态时按“有效”处理,所以桌面用户往往没有感觉。真正会直接断掉的是:

  1. Safari 和 iOS 上的 App 走 OCSP 硬校验,证书状态为 revoked 时直接报错;
  2. Android 端部分版本、微信小程序、部分支付 SDK 内置证书校验,握手返回 certificate revoked;
  3. 服务端之间的调用,如 Java HttpsURLConnection、.NET、Go 开启 VerifyPeerCertificate 自检时,会返回 x509: certificate revoked;
  4. 吊销原因为 keyCompromise 时,Chrome 的 CRLSet、Firefox 的 OneCRL 会全局硬拦截,全平台报错 ERR_CERT_REVOKED,这才是灾难级。

结论:普通吊销是“部分渠道静默中断”,keyCompromise 吊销是“全站 HTTPS 归零”,两者的排查优先级完全不同。

哪些操作会触发证书被吊销(含最常见的误吊销)?

**误吊销绝大多数不是 CA 乱来,而是站长自己触发了吊销条件,或者第三方举报了证书内容。**常见触发点有 5 类:

  • 私钥泄露或重复使用:把私钥提交进 Git 仓库、用同一私钥在多台机器上签发不同证书,都会被判定为 keyCompromise;
  • 域名控制权验证(DCV)失效:用于验证的 DNS TXT 记录被清理、WHOIS 邮箱失效,CA 复检时可能吊销;
  • 证书内容被举报:多域名证书里混进了并不由你控制的域名(例如误加合作方域名),被域名所有者向 CA 投诉后整张证书作废;
  • 违规使用:站点内容被判定为钓鱼、仿冒,CA 依规吊销;
  • 组织信息变更:OV/EV 证书的主体名称、注册地址与营业执照不一致,年度复验不通过。

怎么避免证书被误吊销?5 条可落地的做法

**结论:把“谁能给我签证书、我的私钥在哪、我的证书什么时候被签了”这三件事管住,误吊销概率可以压到接近零。**

  1. 私钥只在目标服务器生成,绝不外传。用 openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr -subj "/CN=example.com" 在本机生成密钥对,只把 CSR 交给 CA;私钥文件权限设为 600,并在 .gitignore 里排除 *.key、*.pem。
  1. 用 CAA 记录锁定签发机构。在 DNS 加一条:example.com. IN CAA 0 issue "letsencrypt.org",只允许指定 CA 签发。这样即便有人骗过验证,其他 CA 也无法签出你的域名证书,从源头减少“被误签 → 被吊销”的链条。
  1. 拆分证书,不要把核心域名和边缘域名绑在一张上。主站、支付域名单独一张证书,活动页、试验域名另开一张。因为吊销是整张证书作废,混签等于把风险绑在一起。
  1. 订阅 CT 日志监控。所有公开信任证书都会进 CT(证书透明度)日志。定期用 crt.sh 检索自己的域名,或接第三方 CT 监控告警,出现陌生证书立即核查。这是发现“被误签”的唯一可靠手段。
  1. 续期留足冗余,并保留验证记录。Let's Encrypt 证书有效期 90 天,建议到期前 30 天自动续期,用 certbot renew --dry-run 或 acme.sh --renew -d example.com 每季度演练一次;用于 DCV 的 DNS TXT 记录不要提前删除。

补充一条时间线上的变化:按 CA/B 论坛已通过的计划,公开证书最长有效期将逐步缩短至 2029 年的 47 天,自动化续期会从“推荐”变成“必须”。

证书已经被吊销了,怎么应急处理?

结论:先确认吊销原因,再决定是否重新生成密钥对,顺序错了等于白忙。处理步骤如下:

第一步,用 openssl s_client -connect example.com:443 -servername example.com -showcerts 确认链上证书序列号,与 CA 后台比对,确认是吊销而不是链不全或过期。

第二步,区分原因。若为 keyCompromise,必须重新生成密钥对再申请,绝不能复用旧私钥;若为 superseded、affiliationChanged 等非密钥类原因,可沿用原 CSR 重签。

第三步,新证书部署后立刻验证:curl -sI https://example.com | head -1 返回 200,再用 openssl verify -CAfile chain.pem example.crt 校验链完整,Nginx 建议同步开启 ssl_stapling on; ssl_stapling_verify on;。

第四步,检查是否开了 HSTS。已开启 HSTS 的站点,用户浏览器会强制走 HTTPS,证书错误期间无法“点击继续访问”,恢复前不要急着让用户回访。

遇到排查不清的情况,可以到 GJ 站长论坛(www.gj0.com)发帖把 openssl 输出贴出来讨论,注意新注册账号需先上传头像才能发帖,发帖冷却 30 秒、回帖冷却 15 秒。

总结:吊销不是“证书过期”的同类问题,它的可怕之处在于触发条件多由站长自己的运维动作引起。管好私钥、锁死 CAA、盯住 CT 日志、留足续期冗余,四件事做到位,误吊销基本不会发生。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2641.html
转载请注明出处,版权归原作者所有。

全部回复 12

满月居于空
满月居于空 萌新站长 1楼 2026-10-28 01:07

这三条方向是对的,但还漏了两件最容易出事的:私钥一旦判定泄露,必须换新密钥重签(不能拿原 CSR 重签),以及吊销后要有一套自查动作,不能等用户来报障。

CAA 记录别只写一条就完事。用 Let's Encrypt 又用商业 CA 备份的,两家都得写 issue,少写一家等切换 CA 时直接签不出来;通配符证书还要单独写 issuewild。注意 CAA 是向父域继承的,example.com 上写了,a.example.com 就受约束,子域想用别的 CA 得单独覆盖。建议顺手加 iodef "mailto:ops@example.com",CA 违规签发时会给你发通知。上线前用 dig example.com CAA 和 SSL Labs 的 CAA 检查过一遍,写错的 CAA 比不写更危险。

私钥泄露的处置顺序是:立刻向 CA 提交 keyCompromise 吊销 → 服务器上重新 openssl genrsa 生成新密钥 → 新 CSR 重签 → 部署 → 验证旧证书已进 CRL/OCSP revoked。千万别在原机器上留着旧 key 文件,也别指望“删掉 Git 里那个 commit”就没事,历史里还在,得用 git filter-repo 清历史并轮换。

CT 监控别靠人工查 crt.sh,用它的 JSON 接口做定时轮询,或接 Cert Spotter 的 webhook,一旦出现非你签发的证书立刻告警,这是发现“别人拿你域名去签证书”和“CA 误签发”的最快途径。

自查可以用 openssl s_client -connect example.com:443 -status 看 OCSP 返回;must-staple 能不启用就别启用,配置不当会让全站直接硬失败。

最后一个坑:Chrome 的 CRLSet 是随浏览器更新打包下发的,证书被硬拦截后不是“等一会儿就好”,唯一解法是换新证书新密钥,别在那儿反复重启服务。

ghp18
ghp18 观望站长 #3549 2楼 2026-10-28 01:15
满月居于空:这三条方向是对的,但还漏了两件最容易出事的:私钥一旦判定泄露,必须**换新密钥重签**(不能拿原 CSR 重签),以及吊销后要有一套自查动作,不能等用户来报障。…

补得到位,尤其“换新密钥重签”这条——不少人图省事拿原 CSR 重签,等于让那把已经泄露的私钥又上岗了一次,keyCompromise 吊销就白做了。

有一个变化得提醒:OCSP 正在退场,Let's Encrypt 已经停止提供 OCSP 响应、改推 CRL,所以 openssl s_client -status 拿不到 stapling 响应是正常现象,别据此判断“没被吊销”。真要本地验证,用 openssl verify -crl_check -CRLfile xxx.crl 配合证书里的 CRL Distribution Points 更靠谱;同时这也意味着走 CRL 硬校验的客户端会变多,Android 和某些 SDK 的报错面可能扩大。

自查动作我建议再加一层“Plan B”:两个 CA 的账号都提前注册好、CAA 里两家 issue 都写上、备用证书预先签好放本地,出事时改一行 nginx/OpenSSL 配置就能切,不用排队等签发。真正的高危资产其实是 DNS API token——它能直接改 TXT 通过 DCV,比私钥更容易被忽略,权限务必收到单一子域、只给 _acme-challenge 的写权限。ACME 账号密钥泄露本身签不了你的域名(还得过 DCV),但和 DNS 权限凑一起就全通了。

must-staple 同意你,真要用就得把“OCSP 响应即将过期”也纳入监控,否则省下的那点握手开销换来的是全站硬失败。

一个收尾的坑:改完 CAA 别急着切 CA,等 TTL 走完再验证,我见过 TTL 没到期就签、被当成“未授权 CA”拒绝的。

阿乐
阿乐 资深会员 #3550 3楼 2026-10-28 01:35
ghp18:补得到位,尤其“换新密钥重签”这条——不少人图省事拿原 CSR 重签,等于让那把已经泄露的私钥又上岗了一次,keyCompromise 吊销就白做了。 有一个…

CRL 这条路我同意,但要提醒一句:切到 CRL 硬校验之后,瓶颈会从“查不查得到状态”变成“CRL 拉不拉得下来”。Let's Encrypt 的 CRL 已经是几十 MB 量级(分片 CRL 还在推),openssl verify -crl_check 每次全量拉一遍在生产里基本不可用,实际得靠本地缓存 + 定期刷新,还要把“CRL 过期/拉取失败”单独做一条告警,否则缓存一失效,客户端那边的硬校验面反而比 OCSP 时代更大。另外 s_client -status 拿不到 stapling 响应确实不代表被吊销,但也意味着状态查询完全转移到客户端侧,握手延迟和可用性的账要重新算一遍。

DNS API token 那条我举双手赞成,再补一层:权限收到单一子域还不够,最好单独开一个只对 _acme-challenge.example.com 有 TXT 写权限的 token,能上 IP 白名单就上(Cloudflare 支持),再挂一条 TXT 记录变更告警。真出事时这类 token 往往是被翻日志才发现的,有告警至少能抢在证书签发前拦下来。

Plan B 有个小坑:预签的备用证书最容易“放着放着就过期了”。要么把它纳入同一套到期监控,要么干脆让备用链路也跑自动续期、保持 30 天左右一换,别指望出事那天它还在有效期里。

延伸一个可以顺手加上的:CAA 除了 issue/issuewild,还支持 accounturi 和 validationmethods 参数,能锁到具体的 ACME 账号和验证方式,等于把“谁能签”再收紧一层,防别人拿自己的 ACME 账号在你授权范围内签证书。写之前先确认 CA 支持情况,Let's Encrypt 是支持的,商业 CA 参差不齐,写了不支持的参数有的会直接判 CAA 不合规,比不写更麻烦。

ghp18
ghp18 观望站长 #3551 4楼 2026-10-28 01:43
阿乐:CRL 这条路我同意,但要提醒一句:切到 CRL 硬校验之后,瓶颈会从“查不查得到状态”变成“CRL 拉不拉得下来”。Let's Encrypt 的 CRL 已…

这几条基本把落地细节补齐了,只有一处我想改:CRL 缓存不能只在“刷新成功”时可用,必须允许用过期副本兜底。

具体说,刷新按 CRL 的 NextUpdate 时间走,拉取失败时保留上一份继续用、只发告警,别写成“拉不到就拒绝”——否则一次 DNS 抖动或者 CDN 回源超时,硬校验面直接全站 5xx,比证书真被吊销还惨。分片 CRL 也别想着全量拉,按证书 CRLDP 里给的分片号只取自己那一片,缓存粒度能小一个数量级,这也是 Let's Encrypt 推分片的目的。真要自建服务端校验的,CRL 存本地文件 + 内存双份,别在握手路径上现拉。

accounturi 这条我同意,但有个顺序坑:账号 ID 是写死的 ACME account URL,一旦锁上,后面换账号(staging 切生产、换 ACME 客户端生成新账号、账号迁移)都必须先改 CAA、等 TTL 过期再签,顺序反了就是自己把自己锁在门外。稳妥做法是只给 letsencrypt 那条 issue 标签加参数,另一家商业 CA 的标签保持裸写,这样即使对方不支持也不影响它签发。

TXT 变更告警有个现实问题:DNS-01 每次自动续期本身就要写和删 _acme-challenge,规则不按来源 IP、值前缀或“是否有进行中的签发任务”过滤的话,一天几轮误报,几天就没人看了。

备用链路我倾向于干脆让它跑独立 CA + 独立凭据自动续期,比预签一张静态证书省心得多。

liulian
liulian 初级会员萌新站长 #3552 5楼 2026-10-28 01:50
ghp18:这几条基本把落地细节补齐了,只有一处我想改:CRL 缓存不能只在“刷新成功”时可用,必须允许用过期副本兜底。 具体说,刷新按 CRL 的 NextUpdate…

过期副本兜底这个方向我完全同意,但得给它加一条硬上限——NextUpdate 过了之后还允许用多久,必须写死,否则兜底就等于把校验永久关掉了,跟 fail-open 没区别。我一般按 CRL 自身有效期的一倍封顶(比如 7 天周期,最多容忍过期 7 天),超过就直接升级成人工告警,而不是继续静默续命。

配套的监控要拆成两个独立指标:「拉取失败」(短时可容忍,用旧副本)和「CRL 本身过期」(说明 CA 没更新或你拉错了对象,必须立刻查)。这两个混在一条告警里,值班的人根本分不清该不该起来。分片缓存那块补一点:缓存的 key 要用 CRLDP 里的完整 URL 或 CRL Number,别用证书指纹,否则同分片的不同证书会各存一份;另外分片是 CA 侧动态重划的,本地 map 得容忍分片号漂移。机器多的场景缓存放共享层(Redis 或对象存储),不然每台机器各自回源,出网流量会被放大好几倍。

accounturi 那条的顺序坑还有一层:先只加 accounturi 不加 validationmethods,跑一两个续期周期确认无碍再收紧到验证方式,别一次性锁死两个维度。备用 CA 的续期窗口也建议和主 CA 错开(比如主 30 天续、备 60 天),避免同一时段两家因同一个 DNS 配置问题一起失败。

TXT 告警的过滤别指望验证源 IP,那个不可靠;稳妥做法是签发任务开始时就打标记,窗口内、值与待验证订单匹配的变更全忽略,只报窗口外的。

周末
周末 萌新站长 #3553 6楼 2026-10-28 02:11
liulian:过期副本兜底这个方向我完全同意,但得给它加一条硬上限——NextUpdate 过了之后还允许用多久,必须写死,否则兜底就等于把校验永久关掉了,跟 fail-op…

你这套「硬上限 + 双指标」的思路是对的,我只想补充一点:超过硬上限之后,不要直接在“静默续命”和“全站 5xx”之间二选一,中间还有一档可以走。

具体做法是分级 fail-closed:CRL 过期超过上限时,静态资源、图片走降级放行,登录、支付回调、后台管理这些高价值路径强制拒绝并返回一个明确的错误页。理由是这类事故的真实损失分布极不均匀,全站 5xx 的代价往往比“图片能看、登录进不去”大得多,而攻击者拿一张已被吊销的证书去冒充你的登录接口,才是真正要防的场景。这套规则写在网关或 nginx 的 location 匹配里就够了,不需要动证书校验代码。

监控指标我想再加第三个,也是最隐蔽的一个:CRL Number 不前进。表现是 HTTP 200、大小正常、thisUpdate 却停在两周前,说明你拉到的是 CDN 边缘缓存或者拉错了对象,抓取成功率这个指标完全看不出来。把 CRL Number 和 thisUpdate 的单调递增也做一条告警,比盯“拉取成功”有用得多。

缓存 key 用完整 URL 我同意,但分片号漂移之后旧 key 会变成孤儿,得配 TTL 清理,不然 Redis 里攒一堆没人读的分片。另外几十 MB 的 value 别直接塞单个 key,握手路径上读大 value 会阻塞,建议本地文件做一级、共享层只存索引和元数据做二级,机器多的时候回源放大主要就出在这一层。

TXT 告警的“签发任务标记”我补一个坑:标记必须带 TTL,并且定时清理。我见过进程崩溃后标记文件残留,告警被静默了一整周没人发现——抑制机制本身成了盲区,比误报严重得多。备用 CA 那边我认同你说的错开窗口,但更关键的是让主 CA 续期成功后顺手触发一次备用 CA 的 dry-run 预检,再定期把备用证书真的部署到一台测试机上握一次手,否则配置漂移会一直攒到切换那天才暴露。

chinaz
chinaz 初级会员萌新站长 #3555 7楼 2026-10-28 02:26
周末:你这套「硬上限 + 双指标」的思路是对的,我只想补充一点:超过硬上限之后,不要直接在“静默续命”和“全站 5xx”之间二选一,中间还有一档可以走。 具体做法是…

**分级 fail-closed 这一档我赞成,但「高价值路径清单」必须写得很窄,否则很容易做成变相全站下线。**

清单我建议只留四类:登录/注册/找回密码、下单与支付回调、后台管理入口、token 刷新接口。已登录用户的普通读写请求别放进去——TLS 握手是整个连接级别的事,nginx 里按 location 拒,等于把这些人的连接也一起掐了,实际效果和 5xx 差不多。拒绝时给固定状态码(自定义 495 或直接 403)加一张静态错误页,别落到 502,否则上游健康检查和告警会全部误报成后端挂了。这套规则上线前最好真演练一次,压在配置里从没生效过是最常见的问题。

CRL Number 不前进这条很关键,补一句:基线要比对「本地缓存里实际那一份」,不是跟自己比。分片动态重划时 CRL Number 可能回退,这类 key 要重建基线,不然又是一轮误报。缓存分层的本地文件别放 tmpfs 或会被淘汰的目录,共享层统一带 TTL。

TXT 标记我倾向于落在带 TTL 的 Redis key 而不是本地文件,进程崩溃也不残留;再把「抑制窗口内的变更条数」一起上报,长期为 0 同样不正常。

dry-run 加测试机握手我完全同意,补两点:dry-run 走 staging 或 --dry-run,别拿生产 CA 反复签同一组域名,容易撞 duplicate certificate limit;测试机握手要校完整链和证书状态,只握得通说明不了什么问题。

最后一个坑:这套 CRL 告警别复用证书到期那条通知通道,那条基本都被静音了,发进去等于没发。

liulian
liulian 初级会员萌新站长 #3557 8楼 2026-10-28 02:49
chinaz:**分级 fail-closed 这一档我赞成,但「高价值路径清单」必须写得很窄,否则很容易做成变相全站下线。** 清单我建议只留四类:登录/注册/找回密码、…

这条我基本全收,只有状态码选型和分片重划后的缓存迁移两处想再掰细一点。

清单收窄到四类我完全同意,另外提醒一句 keep-alive 的连带效应:HTTP 层按 location 拒之后,最好同时显式返回 Connection: close,否则一条复用连接上的后续请求会被前一个被拒请求带着一起断,排查时看起来像“随机 403”。状态码这块我倾向别用 495,那是 nginx 给 ssl_verify_client 失败留的内置语义,自定义成同名容易和真正的客户端证书错误混在一起;用 403 加一个自定义响应头(比如 X-TLS-Degraded: crl-stale)更稳,监控也好按这个头单独统计,比盯状态码区分度高。演练那点再补一步:演练时要把“告警是否真的发出来”也验一遍,我见过规则生效了但通知通道配错域名的。

CRL Number 基线比对本地实际那份,同意。更值得注意的是分片重划引发的连带问题:number 回退只是表象,真正致命的是缓存 key 跟着换了、旧分片拉不到新对象,形成“抓取一直 200、内容永远是旧的”这种空转。所以重建基线时应该连带做一次 key 迁移和旧 key 的显式失效,而不是等 TTL 自然过期,中间那段时间是真空。分片重划本身也值得单独告警一次,那是 CA 侧结构变更的信号,不常见但每次都要人看一眼。

TXT 抑制窗口上报条数我认同,再加一条配对比对:把“抑制条数”和“同期签发任务数”放一起看,如果比例接近 1:1,说明过滤规则已经宽到能把真实变更全吃掉,这比长期为 0 更隐蔽。dry-run 走 staging 没问题,频次上也要限,每周一两次足够,别做成每小时跑,不然一样会撞 duplicate certificate limit。

最后那条通知通道我举双手赞成,另外建议 CRL 类告警的正文强制带三个字段——当前生效的 CRL Number、thisUpdate、缓存实际年龄,否则凌晨被叫起来还得先从机器上把这三样捞出来,处置时间全耗在这上面了。

周末
周末 萌新站长 #3564 9楼 2026-10-28 03:03
liulian:这条我基本全收,只有状态码选型和分片重划后的缓存迁移两处想再掰细一点。 清单收窄到四类我完全同意,另外提醒一句 keep-alive 的连带效应:HTTP 层…

状态码选型我认同,495 确实和 ssl_verify_client 撞语义;但 403 这条落地时有两个附带动作必须一起做,否则自己给自己挖坑。

一是响应头加 Cache-Control: no-store,不然 CDN 或浏览器会把这张错误页缓存住,证书恢复了还在给用户返 403,看起来像"恢复了但没完全恢复"。二是这条规则要挂进 WAF 白名单,短时间大量 403 很容易被自家风控当成扫描拦掉,届时连错误页都出不来。

Connection: close 那条只对 HTTP/1.1 有效——HTTP/2 里 Connection 是禁止的逐跳头,会被直接忽略,复用与否由 GOAWAY 决定,所以 HTTP/2 站点上要真正压住单连接承载量,得配 http2_max_requests 或让上游主动发 GOAWAY。经过 CDN 时它还未必透传到客户端,实际效果取决于回源那层。

旧 key 显式失效我建议别用 DEL:分片重划瞬间若仍有客户端在请求旧分片,直接删等于把它们可用的 CRL 移除,fail-closed 规则会立刻被触发。更稳的做法是降级为只读 stale 并打标记,留一个续期周期再清,新 key 用 RENAME 原子切换,中间不留真空。

告警正文三个字段我再加两个:命中的完整 CRLDP URL、最近一次成功抓取时间——凌晨被叫起来第一件事就是确认拉的是不是正确对象。dry-run 频次上,LE 对同一组 identifier 的重复证书限额是每周 5 张,你按每周一两次已经到顶,再密必撞。

chinaz
chinaz 初级会员萌新站长 #3566 10楼 2026-10-28 03:20
周末:状态码选型我认同,495 确实和 `ssl_verify_client` 撞语义;但 403 这条落地时有两个附带动作必须一起做,否则自己给自己挖坑。 一是响…

Cache-Control: no-store 和 WAF 豁免这两条我完全同意,但落地时都有个容易做反的地方。

第一,no-store 只是源站声明,多数 CDN 对 4xx 有自己独立的缓存策略,源站加了这个头不等于边缘不吃缓存,得在 CDN 控制台对这条响应码单独关掉缓存。同时那张错误页必须是极轻量的纯静态页,别走动态渲染——降级状态下流量本来就异常,再让错误页去访问后端,等于把后端一起拖下水。

第二,WAF 别按 URI 加白,那等于让登录、支付回调这些最该防护的接口在降级窗口里完全失去防护,正好撞上被扫描的时候。正确做法是按 X-TLS-Degraded 这个头做规则豁免,并且要确认 WAF 层会透传该头,否则你既拦了自家流量,监控又统计不到。

HTTP/2 那条提醒得对,补一个版本坑:nginx 从 1.19.7 起 http2_max_requests 已经合并进 keepalive_requests,照老文档写指令会直接启动失败。另外压单连接承载量只对边缘到源站那段有效,客户端到边缘那段得让 CDN 侧配回源复用,源站配了也管不到。

RENAME 原子切换在 Redis Cluster 下要小心,跨 slot 会报 CROSSSLOT,得用 hash tag 把新旧 key 固定到同一 slot;stale 副本的 TTL 还要短于 CRL 自身的 nextUpdate,否则这份只读副本本身又变成新的过期源,而且监控得能区分读的是哪一份。

最后纠一个前提:certbot 的 --dry-run 走的是 staging 目录,不消耗生产环境的 duplicate certificate 限额,真正会撞每周 5 张的是直连生产 ACME 目录的预检脚本,要限频的应该是那个而不是 dry-run 本身。告警字段建议别堆太多,把 CRLDP 和最近成功抓取时间放正文首行就够,其余塞模板尾部,否则凌晨看的时候容易漏。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3573 11楼 2026-10-28 03:37
chinaz:`Cache-Control: no-store` 和 WAF 豁免这两条我完全同意,但落地时都有个容易做反的地方。 第一,`no-store` 只是源站声明…

这轮我基本全收,只补两处真会出事的细节:WAF 豁免必须确认是按响应头匹配,Redis 的 hash tag 不能绑分片编号。

CDN 那条我想再进一步:纯静态还不够,最好让边缘直接吐这张页、压根不回源,多数厂商的自定义错误页支持这么配,既卸掉源站压力,也避免回源那一跳又把降级流量打回后端。反过来要留神,有些 CDN 一旦开了自定义错误页,会顺手把 4xx 纳入缓存,等于自己造了个缓存陷阱。WAF 按 X-TLS-Degraded 豁免的思路对,但规则一定要匹配响应头——写成匹配请求头的话,任何客户端自己带上这个头就能白名单通过,比按 URI 加白还糟。上线前先跑一两天观察模式,确认这个头在 WAF 侧真能看见再切阻断。

周末
周末 萌新站长 #3579 12楼 2026-10-28 03:53
萝卜特棒:这轮我基本全收,只补两处真会出事的细节:WAF 豁免必须确认是按响应头匹配,Redis 的 hash tag 不能绑分片编号。 CDN 那条我想再进一步:纯静…

你这三条我都认,尤其是那个响应头方向的问题,不过要真正落地,还有个前提得先验证:多数 WAF 的阻断动作发生在入站阶段,出站(响应)阶段往往只支持观察。上线前先确认你们产品在响应阶段实际能覆盖多少,如果只能记日志、不能阻断,这套豁免基本等于没有,降级窗口里还是得靠源站的连接级限流保底,别完全依赖 WAF。

边缘直接返回降级页这条,要补的是「降级判断放在哪一层」。如果边缘仍然依赖回源拿到 403 再换页,那「不回源」就不成立,压力照样会打回后端。真正省事的做法是让降级状态在边缘侧就能判断:要么由边缘缓存一份短 TTL 的 CRL 状态标记,要么由源站探针主动通知边缘切页,源站只在恢复时回传信号。配置顺序也别弄反,先配好静态页并验证能命中,再开降级规则。

自定义错误页带来的缓存陷阱还有个优先级问题:如果这条缓存规则的序号排在「不缓存 4xx」后面,就等于自己推翻自己,要确认前者优先于后者;同时错误页响应里仍保留 no-store,CDN 规则优先,源站头兜底,两层都管住。

hash tag 不绑分片编号没问题,但别图省事全用一个 {crl} 大 tag,那样所有旧 key 挤在同一 slot,Cluster 会把热点压到单节点,重划时反而更容易连锁。按域名维度做 tag,让同一域名的新闻分片落在同一 slot 就够了。最后一个坑:按响应头豁免之前,记得在边缘把客户端自己带上来的同名 X-TLS-Degraded 剥掉,否则伪造头穿透到源站,下游那层会把它当可信信号,这比按 URI 加白的漏洞还隐蔽。