单纯写 ssl_early_data on 不会实现 0-rtt,必须同时满足:nginx≥1.15.5 且 openssl≥1.1.1(编译与运行时均需验证)、server 块中配置 ssl_protocols tlsv1.2 tlsv1.3、ssl_session_cache 或 ssl_session_tickets 启用会话复用、后端识别 early-data 头并拒绝非幂等操作。

单纯在 Nginx 配置里写 ssl_early_data on; 不会自动实现零往返(0-RTT)传输。它只是启用 TLS 1.3 下 early data 的入口开关,真正跑起来需要协议栈、会话机制、客户端状态和后端逻辑四者协同就位。
底层组件必须真实支持 TLS 1.3
Nginx 和 OpenSSL 的实际运行版本与链接关系决定能不能走 0-RTT:
- Nginx 版本需 ≥ 1.15.5(推荐 1.19.0+ 或 1.24.x),执行
nginx -v只看版本号不够,要用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 编译时实际链接的版本——查
nginx -V中 configure 参数里的 OpenSSL 路径,再进该路径执行./bin/openssl version - 验证 TLS 1.3 套件是否可用:运行
openssl ciphers -v 'TLSv1.3',输出中至少要有TLS_AES_256_GCM_SHA384、TLS_CHACHA20_POLY1305_SHA256、TLS_AES_128_GCM_SHA256这三条原生套件
server 块内必须配齐最小必要组合
该指令只在 HTTPS 的 server 块中生效,全局或 location 内设置无效:
- 协议必须双启:
ssl_protocols TLSv1.2 TLSv1.3;—— TLSv1.2 是 PSK 协商基础,不能省;TLSv1.3 是 0-RTT 唯一载体 - 密钥套件要纯 TLS 1.3:
ssl_ciphers 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_early_data on;,并建议加ssl_conf_command Options -PrioritizeChaCha;提升移动端成功率
客户端行为决定是否真触发 0-RTT
服务端全配对,不等于每次请求都走零往返:
- 浏览器需已访问过该域名至少一次,且未清空缓存或退出隐私模式——PSK 缓存在客户端本地,首次访问或清缓存后失效
- 若流量经过 CDN、反向代理或中间网关,它们也必须支持 TLS 1.3 及
early_data扩展,否则握手退化为 1-RTT - 0-RTT 仅对天然幂等的请求有效:CSS/JS/字体/图片等静态资源、公开只读 API、带 token 校验的 GET 接口(如
/user/profile)、已缓存且不含动态 CSRF 的登录页 HTML
后端必须识别并承担安全责任
Nginx 不拦截、不校验 early data,只负责透传:
- 通过
proxy_set_header Early-Data $ssl_early_data;将标识(值为"1"表示 0-RTT)明确传递给上游服务 - 后端收到
Early-Data: 1时,禁止执行任何非幂等操作:登录、下单、转账、表单提交一律拒绝,建议统一返回425 Too Early - 对静态资源或只读接口可放行,但需确保无副作用(例如不能因响应而更新计数器或日志)
- 若业务确需 0-RTT 写操作(极少见),必须叠加应用层防护:一次性请求 ID + ≤5 秒时间窗口 + Redis 去重记录











