开启SSL会话票据需用外部48字节二进制密钥文件+多密钥轮换机制,禁用静态单密钥;Nginx仅首密钥加密新票据,全部密钥均可解密旧票据;推荐njs动态加载密钥以支持Vault等中心化服务。

直接用 ssl_session_tickets on 开启会话票据只是第一步,真正实现高性能又高安全的重用,关键在密钥管理——必须用外部二进制密钥文件 + 多密钥轮换机制,不能依赖静态单密钥或配置内硬编码。
密钥必须是 48 字节二进制文件,且严格隔离权限
OpenSSL 生成一次即固定,不可重复运行:
openssl rand 48 > /etc/nginx/ticket.key.v20260430- 立即设为仅 root 可读:
chmod 400 /etc/nginx/ticket.key.v20260430 - 绝对不要用 base64、hex 或文本格式;Nginx 只接受原始二进制
- 所有集群节点必须分发**完全相同的文件**,否则跨节点票据无法解密
配置多个密钥实现平滑轮换,兼顾安全与可用
Nginx 按顺序加载最多 10 个 ssl_session_ticket_key,规则明确:
由 ReMe 驱动的记忆管理系统,支持跨会话记忆持久化、自动应用用户偏好以及智能上下文压缩...
- 只有第一个密钥(索引 0)用于加密新票据
- 全部列出的密钥都可用于解密旧票据(含已下发但未过期的)
- 轮换时:新增密钥放最前 → 重载或重启 Nginx → 几天后移除最老密钥
- 示例配置(当前主密钥为 v20260430,兼容 v20260330 和 v20260228):
ssl_session_ticket_key /etc/nginx/ticket.key.v20260430;
ssl_session_ticket_key /etc/nginx/ticket.key.v20260330;
ssl_session_ticket_key /etc/nginx/ticket.key.v20260228;
用 njs 实现动态密钥加载(推荐用于多环境/密钥中心化场景)
若需对接 Vault、Consul 或自动密钥服务,njs 是更灵活的选择(需 Nginx ≥ 1.19.4 + nginx-extras):
- 在
http块中引入脚本:js_import session_tickets.js; - 配置指令:
ssl_session_ticket_key $session_tickets_key; -
session_tickets.js中可读取本地文件、远程 API 或环境变量,拼接多个 48 字节密钥返回 - 密钥变更后无需 reload,njs 函数每次握手时实时提供最新密钥列表
验证是否生效:两步命令确认复用真实发生
不用抓包,终端直连即可判断:
- 首次连接(建立新会话):
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | grep "New, TLS"—— 应显示New, TLSv1.3或类似 - 立即二次连接(携带票据重试):
openssl s_client -connect example.com:443 -servername example.com -reconnect 2>/dev/null | grep "Reused, TLS"—— 若出现Reused即表示票据复用成功










