直接启用ssl_early_data on仅开启0-rtt入口,真正实现“发包即响应”需nginx≥1.15.5、openssl≥1.1.1且运行时匹配、server块中配置双协议tlsv1.2/tlsv1.3、启用会话复用及ssl_early_data on,后端还须校验early-data头并拒绝非幂等操作。

直接写 ssl_early_data on 不会自动“秒开”,它只是打开 TLS 1.3 零往返(0-RTT)的入口。真正实现请求发出去就收到响应,需要协议、缓存、客户端、后端四者严丝合缝——缺一不可,否则静默降级为 1-RTT,且无任何报错提示。
确认底层是否真支持 0-RTT
很多配置看似正确,实则根本没跑起来,卡在第一步:
- 运行
nginx -V 2>&1 | grep -i openssl,确认编译时链接的是 OpenSSL ≥ 1.1.1(如 1.1.1w 或 3.0.x) - 再执行
ldd $(which nginx) | grep ssl,查出实际加载的libssl.so路径,然后用objdump -T /path/to/libssl.so | grep TLSv1_3_client_method验证 TLS 1.3 符号存在 - Nginx 版本必须 ≥ 1.15.5(推荐 1.19.0+),
nginx -v只看版本号不够,必须验证运行时 OpenSSL 是否匹配
server 块内最小必要配置组合
该指令只在 HTTPS 的 server 块中生效,全局或 location 内写都无效:
- 必须启用双协议:
ssl_protocols TLSv1.2 TLSv1.3(TLSv1.2 不可省,是 fallback 基础;TLSv1.3 必须含,否则无法生成 PSK) - 必须开启会话复用:
ssl_session_cache shared:SSL:10m;或ssl_session_tickets on;(没有它,PSK 无法存储或恢复,0-RTT 直接失效) - 显式开启:
ssl_early_data on;,并建议加ssl_conf_command Options -PrioritizeChaCha;提升移动端协商成功率
哪些请求真能“发包即响应”
0-RTT 不是通用加速器,只对天然幂等、高频复用的请求起效:
- CSS、JS、字体、图片等静态资源:浏览器可在 ClientHello 中直接塞入首个 CSS 请求,服务器校验 PSK 后立刻返回,TTFB 可压至接近网络延迟本身
- 公开只读 API(如城市列表、公告栏):不依赖用户身份、无副作用,可直答
- 带 token 校验的只读接口(如
GET /user/profile):只要校验逻辑无状态变更,就适配 - 已缓存且不含动态 CSRF 的登录页 HTML:在 HTTP/3 场景下尤为明显,Initial 包即可携带
后端必须承担安全决策责任
Nginx 从不拦截或校验 early data,只负责透传。风险全由后端承接:
- 通过
proxy_set_header Early-Data $ssl_early_data;显式传递标识(值为"1"表示 0-RTT) - 后端收到
Early-Data: 1时,必须拒绝所有非幂等操作:登录、下单、转账、表单提交一律禁止,建议统一返回425 Too Early - 对 GET 类静态资源或只读接口,可放行,但需确保无副作用(例如不能顺手刷新 token)
- 若极少数业务必须支持 0-RTT 写操作,需自行实现防重放:一次性请求 ID + ≤5 秒时间窗口 + Redis 去重记录,三者缺一不可











