Nginx原生不支持TLS 1.3 PSK配置,包括resumption和external PSK;仅通过Session Tickets实现隐式PSK的0-RTT会话恢复,无ssl_psk_*指令,替代方案需依赖ticket密钥共享或外部代理。

Nginx 原生不支持 TLS 1.3 PSK(Pre-Shared Key)模式,无论是会话恢复型 PSK(如 resumption PSK),还是外部配置的外部 PSK(external PSK),目前(截至 2026 年 5 月)OpenSSL 和 Nginx 均未开放对 TLS 1.3 PSK 的用户级配置接口。
这不是配置遗漏或参数写错的问题,而是底层实现层面的限制。
Nginx 与 TLS 1.3 PSK 的实际支持现状
-
OpenSSL 1.1.1+ 确实实现了 TLS 1.3 PSK(包括
early_data和psk_key_exchange_modes),但仅面向开发者通过 API 调用,不暴露给 Nginx 的配置指令层。 - Nginx 的 SSL 模块通过 OpenSSL 的
SSL_CTX_set_psk_use_session_callback等机制管理会话复用,但它:- 仅使用 session ticket 或 session ID 方式做 TLS 1.3 会话恢复(即隐式 PSK);
-
不提供
ssl_psk_file、ssl_psk_keys或类似ssl_early_data on的独立开关; -
ssl_early_data指令在 Nginx 中不存在(对比 Apache 的SSLEarlyData on,Nginx 尚未实现)。
✅ 正确事实:Nginx 支持 TLS 1.3 的 0-RTT 会话恢复(本质是基于 ticket 的隐式 PSK),但不支持管理员手动注入或管理 PSK 密钥,也无法启用外部 PSK 认证模式(如 IoT 场景中设备预置密钥直连)。
当前可用的“类 PSK”能力:Session Tickets(推荐替代方案)
虽然不能配 PSK,但可通过以下方式获得接近 PSK 的效果:
-
启用并安全配置 TLS 1.3 Session Tickets
ssl_session_cache shared:SSL:10m; ssl_session_timeout 4h; ssl_session_tickets on; # 必须开启(默认即 on) ssl_session_ticket_key /etc/nginx/ssl/ticket.key; # 32 字节二进制密钥文件
-
ssl_session_ticket_key是关键:它用于加密/解密 ticket 内容(含主密钥派生信息); - 同一集群所有 Nginx 实例必须共享同一 ticket key,才能跨节点复用会话;
- 每次更新 key 会导致旧 ticket 失效(可轮换,但需灰度);
- 该机制在 TLS 1.3 下自动适配为 PSK-based 0-RTT 恢复(若客户端支持且服务端允许)。
-
-
控制 0-RTT 行为(间接影响 PSK 使用)
# Nginx 不直接控制 0-RTT,但可通过以下方式约束: add_header Timing-Allow-Origin "*"; # 更重要的是:确保上游或应用层能安全处理重放请求(0-RTT 请求可被重放)
⚠️ 注意:0-RTT 数据存在重放风险,Nginx 不校验重放,业务逻辑必须自行防御(如一次性 token、时间窗口校验等)。
为什么你找不到 ssl_psk_* 配置项?
因为这些指令从未被加入 Nginx 官方代码库:
- Nginx 的
src/event/openssl/模块中没有解析psk相关配置的逻辑; -
ngx_http_ssl_module.c中无psk_file、psk_keys等指令注册; - GitHub issues 和邮件列表中多次有人提出需求(如 #5987),但官方回应明确:“PSK 不在当前支持范围内,优先保障标准证书认证路径”。
替代方案建议(按场景)
| 场景 | 可行做法 |
|---|---|
| 内网微服务间轻量互信 | 改用 mTLS(双向证书)+ 短期证书 + SPIFFE/SVID;或改用 gRPC+ALTS、Istio mTLS |
| IoT 设备直连 Nginx(需预置密钥) | 在前端加一层轻量代理(如 Envoy 或自研 Go 服务),由其处理 PSK 握手,后转 HTTP 到 Nginx |
| 需要 0-RTT 加速首屏 | 依赖 Session Ticket + HTTP/2 或 HTTP/3(需 QUIC 支持),确保 ssl_buffer_size 4k; 等调优到位 |
| 合规审计要求显式 PSK 记录 | 当前无法满足,需更换支持 PSK 的反向代理(如 Caddy v2.8+、Apache httpd 2.4.59+) |
验证你的 TLS 1.3 会话是否走 ticket 恢复(即隐式 PSK)
- 启用 OpenSSL 调试日志:
error_log /var/log/nginx/ssl_debug.log debug;
- 发起两次 curl(带相同 SNI 和 ALPN):
curl -I --http1.1 https://example.com curl -I --http1.1 https://example.com
- 查看日志中是否出现:
SSL_new: New session created SSL_new: Reusing session from cache TLS client hello, first handshake / resumed
若第二条显示
resumed,说明 ticket 复用成功,底层已启用 TLS 1.3 PSK 恢复逻辑。
不复杂但容易忽略。


















