要启用 nginx tls 1.3 的 0-rtt,需满足:nginx ≥1.15.5 且 openssl ≥1.1.1;server 块中配置 ssl_protocols、ssl_ciphers、ssl_early_data on 及会话复用;透传 early-data 头并限制非幂等方法;后端须校验并拒绝非幂等 0-rtt 请求。

要在 Nginx 中真正启用 TLS 1.3 的 0-RTT(Early Data),不能只加一行 ssl_early_data on。它是一套需软硬件、协议栈、会话机制和后端协同的完整配置,缺一不可,否则会静默失效。
基础运行环境必须达标
0-RTT 不是“配了就生效”,底层依赖非常刚性:
- Nginx 版本 ≥ 1.15.5(推荐 1.24.x 或更高),且编译时链接的是 OpenSSL 1.1.1+(不是系统默认的 1.0.2 或 1.1.0)
- 执行
nginx -V查看 configure 参数中 OpenSSL 路径;再用openssl version和ldd $(which nginx) | grep ssl确认运行时加载的 so 文件版本一致且 ≥ 1.1.1 - 证书私钥文件权限需允许 Nginx 读取;SELinux/AppArmor 若启用,须放行 SSL 会话票据读写
server 块内关键 TLS 配置
所有指令都必须写在具体 HTTPS 的 server 块中,全局设置无效:
-
ssl_protocols TLSv1.2 TLSv1.3;—— 必须同时包含 TLSv1.2 作为兼容兜底,不能只写 TLSv1.3 -
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256';—— 仅限 TLS 1.3 原生套件,混入 ECDHE-RSA-AES256-SHA 等 TLS 1.2 套件会导致协商异常或降级 -
ssl_early_data on;—— 核心开关,仅在此 server 块内生效 - 启用会话复用:
ssl_session_cache shared:SSL:10m;或ssl_session_tickets on;,并设ssl_session_timeout 4h;(默认 48h 太长,建议缩至数小时以控重放窗口) - 推荐加
ssl_conf_command Options -PrioritizeChaCha;,因 ChaCha20 是 0-RTT 加密默认算法,优先可减少客户端 fallback 延迟
透传标识并约束请求类型
Nginx 不校验 Early Data 内容,但必须明确告诉后端“这是 0-RTT 请求”,并限制其适用范围:
- 通过反向代理头传递:
proxy_set_header Early-Data $ssl_early_data;(对 proxy_pass)或fastcgi_param TLS_EARLY_DATA $ssl_early_data;(对 PHP-FPM) - 用
limit_except在 location 块中禁止非幂等方法走 0-RTT:limit_except GET HEAD { deny all; } - 对敏感路径(如
/login、/api/submit)单独配置 location,强制返回425 Too Early或跳过 early data 处理
后端必须承担安全决策
Nginx 只做识别与转发,真正的防护闭环在应用层:
- 后端收到
Early-Data: 1头后,只允许响应幂等操作:GET /static/css/app.css、GET /api/status 等 - 任何 POST/PUT/DELETE 请求,必须拒绝并返回
425 Too Early,由前端捕获后自动重发(注意 Chrome 对 425 的自动重试不完全可靠,建议 JS 主动判断重发) - 若业务确需 0-RTT 写操作(极少见),必须叠加一次性 token + 时间戳(≤ 5 秒)+ 请求指纹(如 body hash + IP + UA 哈希)三重校验











