单纯加ssl_early_data on无法实现可用0-RTT,必须同时满足Nginx≥1.15.5、OpenSSL≥1.1.1且正确编译链接、server块中配置TLSv1.2+TLSv1.3协议与会话复用、客户端缓存有效PSK、后端识别Early-Data头并拒绝非幂等操作。

单纯在 Nginx 配置里加一句 ssl_early_data on,无法实现真正可用的 0-RTT。它只是“门把手”,开门需要四把钥匙同时插对:协议支持、会话复用、客户端缓存、后端防护。缺一不可,否则不是不生效,就是埋下重放风险。
底层组件必须真实就绪
Nginx 和 OpenSSL 的版本与编译方式决定能不能跑 TLS 1.3 和 0-RTT:
- Nginx 必须 ≥ 1.15.5(推荐 1.19.0+ 或 1.24.x),运行
nginx -V 2>&1 | grep -o '1\.15\.[5-9]\|1\.[1-9][6-9]\.|2\.'确认 - OpenSSL 必须是 ≥ 1.1.1(如 1.1.1w 或 3.0.x),且是 Nginx 编译时链接的版本——不能只看
openssl version输出,要查nginx -V中 configure 参数里的 OpenSSL 路径,再进该路径执行./bin/openssl version - 执行
openssl ciphers -v 'TLSv1.3',输出至少包含TLS_AES_256_GCM_SHA384、TLS_CHACHA20_POLY1305_SHA256等三条原生套件,否则 TLS 1.3 未真正启用
server 块内配置必须协同精准
0-RTT 是 TLS 1.3 握手路径下的特性,所有配置必须围绕它设计,不能套用旧模板:
-
ssl_protocols TLSv1.2 TLSv1.3:TLSv1.2 不可省,它是兼容兜底和 PSK 协商基础 -
ssl_ciphers只列 TLS 1.3 原生套件,例如:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
禁用所有 TLS 1.2 套件(如ECDHE-RSA-AES256-SHA),混入会导致协商失败或降级 - 启用会话复用机制:
ssl_session_cache shared:SSL:10m;和ssl_session_timeout 4h;
或ssl_session_tickets on;(推荐两者都开) - 加上
ssl_conf_command Options -PrioritizeChaCha,提升移动端 0-RTT 成功率 -
ssl_early_data on;必须放在具体 HTTPS 的server块中,全局配置无效
客户端行为决定是否真走 0-RTT
服务端全配对,不代表每次请求都走 0-RTT。它依赖客户端状态和网络链路:
- 浏览器需已访问过该站点至少一次,并成功缓存了 PSK(通常退出隐私模式、清空缓存后失效)
- 若使用 CDN 或中间代理,节点本身必须支持 TLS 1.3 和 early_data 扩展,否则握手退化为 1-RTT
- 用户首次访问、或跨设备/新浏览器打开,仍走标准 1-RTT,0-RTT 仅对“熟客”生效
后端必须主动识别并安全处理 Early-Data
Nginx 不校验、不拦截、不重放防护,它只负责透传。安全责任完全落在后端:
- 通过
proxy_set_header Early-Data $ssl_early_data;将标识(值为1或空)明确传给上游应用 - 后端收到
Early-Data: 1时,禁止执行任何非幂等操作:登录、下单、支付、表单提交、数据库写入一律拒绝,建议返回425 Too Early引导客户端降级重发 - 对 GET 类静态资源、公开 API、带 token 校验的只读接口,可直接响应,但需确保无副作用
- 若业务强依赖 0-RTT 写操作(极少见),必须叠加应用层防重放:一次性请求 ID + 时间窗口(≤10 秒)+ Redis 去重记录


















