Expect-CT 是 HTTP 响应头,用于要求浏览器检查证书是否记录在 CT 日志中以防范恶意证书;Nginx 通过 add_header 配置 enforce=0(监控)或 enforce=1(强制),需配合合规 CA 和 report-uri 接收服务。

Expect-CT 是 HTTP 响应头,用于要求浏览器检查网站证书是否已记录在公开的证书透明度(Certificate Transparency, CT)日志中,从而防范恶意或错误签发的 TLS 证书被滥用。Nginx 本身不生成或验证 CT 日志,但可通过设置该响应头启用监控模式(enforce=0)或强制执行模式(enforce=1),配合合规的 CA 和日志策略使用。
Expect-CT 基本语法与取值含义
该头部格式为:
Expect-CT: enforce, max-age=86400, report-uri="https://example.com/report"
- enforce:启用强制执行——若证书未出现在任一 CT 日志中,现代浏览器将拒绝连接(仅对支持 Expect-CT 的浏览器生效,如 Chrome 70+;注意:Chrome 已于 2022 年移除此功能,目前主流浏览器不再强制执行)
- max-age:以秒为单位,指定浏览器缓存该策略的时间(建议初设为 86400,即 24 小时,验证稳定后再逐步延长)
- report-uri:指定接收违规报告的端点(需自行部署接收服务,否则报告会被丢弃;HTTP/HTTPS 均可,但必须可被公网访问且返回 200)
- 不加
enforce即为监控模式(仅上报,不阻断),更推荐当前阶段使用
Nginx 中配置 Expect-CT 响应头
在 server 块或 location 块中添加如下指令(推荐放在 HTTPS server 块内):
add_header Expect-CT "enforce=0, max-age=86400, report-uri=\"https://yourdomain.com/ct-report\" always;
-
always参数确保即使返回 3xx/4xx/5xx 状态码也携带该头(重要,否则错误页可能漏报) -
report-uri必须是有效、可写入、带正确 CORS 或无跨域限制的接收地址(例如用 Flask/FastAPI 写一个简单 POST 接口存日志) - 避免在 HTTP server 块中设置,防止明文传输泄露策略意图
- 确认 Nginx 版本 ≥ 1.7.5(
add_header ... always自 1.7.5 引入)
配套准备:CT 日志兼容性与证书签发要求
Expect-CT 生效的前提是证书本身满足 CT 要求:
- 主流公共 CA(如 Let’s Encrypt、DigiCert、Sectigo)自 2018 年起已默认将证书提交至多个 CT 日志,无需额外操作
- 若使用私有 CA 或旧版中间证书,需确认其根证书是否被浏览器信任且对应证书已入日志(可用 crt.sh 查询域名证书是否被收录)
- Let’s Encrypt 签发的证书通常会在数分钟内出现在多个日志中;若延迟超过 1 小时,可手动提交至 Google AVA 或 公开日志列表
验证与调试技巧
配置后务必验证实际响应头是否生效:
- 用
curl -I https://yoursite.com检查响应头是否含Expect-CT - 访问 SSL Labs Test,查看 “HTTP Security Headers” 部分是否识别该头
- 在 Chrome DevTools → Network → Header 标签页中检查任意 HTTPS 请求的响应头
- 主动触发测试报告:临时将
enforce=1+ 构造一张未入日志的测试证书(仅限测试环境),观察是否收到 report-uri 的 POST 数据(生产环境切勿启用 enforce=1)


















