Nginx中PSK模式是TLS 1.3实现0-RTT的核心机制,需OpenSSL 1.1.1+编译、显式启用ssl_session_tickets on与ssl_session_cache、客户端复用票据,且不支持原生PSK密码套件。

PSK(Pre-Shared Key)模式是 TLS 1.3 实现“跳过握手”、达成 0-RTT(Zero Round Trip Time)连接的核心机制,但它在 Nginx 中并非开箱即用——需满足 OpenSSL 1.1.1+ 编译支持、显式启用会话复用策略,并严格匹配 PSK 密钥生命周期与客户端行为。仅配置 ssl_protocols TLSv1.3 不会自动触发 0-RTT,必须配合 PSK 相关指令和密钥管理。
PSK 模式在 Nginx 中的生效前提
Nginx 自身不生成或分发 PSK,它只支持通过 ssl_session_tickets on 启用基于票据(ticket-based)的 PSK 协商,且依赖 OpenSSL 底层实现。关键条件包括:
- OpenSSL 版本 ≥ 1.1.1(含 TLS 1.3 和 PSK 票据支持),且 Nginx 必须用该版本编译(
--with-openssl=) - Nginx 版本 ≥ 1.13.0(官方支持 TLS 1.3)
- 必须启用会话票据:
ssl_session_tickets on;(默认为 on,但不可省略显式声明) - 不能禁用会话缓存:
ssl_session_cache需保留(如shared:SSL:50m),否则票据无法绑定上下文 - 客户端必须在首次完整握手后保存并重用票据(现代 Chrome/Firefox/Edge 均支持,但需用户未清空 TLS 状态)
启用 0-RTT 的最小化配置片段
以下配置聚焦于让 Nginx 正确发送和接受 PSK 票据,从而允许客户端发起 0-RTT 数据:
server {
listen 443 ssl http2;
server_name example.com;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256';
# 关键:启用票据(即 PSK 载体)
ssl_session_tickets on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
# 可选但推荐:限制票据加密密钥轮换频率,提升安全性
ssl_session_ticket_key /etc/nginx/ticket.key; # 48 字节二进制密钥,权限 600}
注意:ssl_session_ticket_key 文件需手动创建(如用 openssl rand 48 > /etc/nginx/ticket.key),多 worker 进程共享同一密钥才能解密票据;若不指定,Nginx 自动生成临时密钥,重启后旧票据失效,影响 0-RTT 连续性。
验证 PSK 是否真正生效
不能仅凭配置存在就认为 0-RTT 已启用,必须实测协商结果:
-
抓包确认:用
tcpdump -i any -w tls13.pcap port 443抓取客户端首次访问后的第二次请求,Wireshark 中查看 Client Hello →pre_shared_key扩展是否出现,且 Server Hello 返回early_data_indication -
日志辅助:开启 Nginx debug 日志(
error_log /var/log/nginx/debug.log debug;),搜索ssl ticket或PSK关键字,确认票据生成与复用记录 -
curl 检查:使用支持 0-RTT 的 curl(≥7.65.0 + OpenSSL 1.1.1+),加
--verbose观察是否出现* Using HTTP2, server supports multi-use和早期数据提示;也可用 Cloudflare TLS 1.3 测试页 快速验证
0-RTT 的安全边界与规避风险
0-RTT 允许客户端在第一个往返中发送应用数据,但存在重放攻击(replay attack)风险。Nginx 本身不提供重放防护,需业务层配合:
- 敏感操作(登录、支付、状态变更)禁止使用 0-RTT 数据,应在完整握手后传输
- 后端服务需识别并拒绝重复的 early data 请求(可通过
$ssl_early_data变量判断,值为1表示该请求含 early data) - 避免在 0-RTT 中携带非幂等操作或认证凭证(如 session token)
- 如无需 0-RTT,可显式禁用:
ssl_early_data off;(Nginx 1.15.5+ 支持)


















