nginx通过多ssl_session_ticket_key配置实现密钥轮转,仅首密钥加密新票据,全部密钥均可解密旧票据;需严格48字节二进制文件,新增密钥置顶、reload生效,配合脚本与cron可实现准自动轮转。

启用 ssl_session_tickets 后,密钥长期不变会带来安全风险——一旦泄露,所有历史票据都可被解密重放。Nginx 本身不提供自动轮转功能,但可通过配置多密钥 + 外部脚本协同实现“准自动”轮转,兼顾安全性与服务连续性。
密钥轮转的核心机制
Nginx 支持按顺序加载最多 10 个 ssl_session_ticket_key 指令,规则明确:
- 仅第一个密钥用于加密新票据(即客户端下次连接收到的票据)
- 所有已列出的密钥均可解密旧票据(包括已下发但尚未过期的票据)
- 密钥文件必须严格为 48 字节二进制数据,不可用文本或 Base64 替代
- 新增密钥需追加到配置末尾,不能替换原有文件(否则旧票据立即失效)
手动配置多密钥的推荐方式
在 http 或 server 块中按时间顺序声明密钥文件,例如:
ssl_session_tickets on; ssl_session_ticket_key /etc/nginx/ticket.key.v20260401; # 当前主密钥(最新) ssl_session_ticket_key /etc/nginx/ticket.key.v20260301; # 上月密钥 ssl_session_ticket_key /etc/nginx/ticket.key.v20260201; # 更早密钥
每次轮转只需:
- 生成新密钥:
openssl rand 48 > /etc/nginx/ticket.key.v20260401 - 更新 Nginx 配置,将新密钥行加在最前面(注意:不是替换,是新增并置顶)
- 执行
nginx -s reload(多数版本支持热重载,无需 full restart)
用 cron + 脚本模拟“自动”轮转
虽无内置调度,但可借助系统定时任务实现周期性更新:
- 每月 1 日凌晨 2 点生成新密钥并更新配置(如用 sed 插入新密钥行)
- 脚本中检查密钥文件是否存在、是否为 48 字节,避免配置错误导致 reload 失败
- 保留最近 3–4 个密钥即可,旧密钥可归档或删除(TLS 票据默认有效期约 4 小时,远短于密钥保留窗口)
- 配合日志记录每次轮转时间与密钥指纹,便于审计追踪
验证轮转是否生效
关键看两点:
- 新连接是否使用新密钥加密票据:用
openssl s_client -connect example.com:443 -reconnect多次抓包,对比NewSessionTicket内容是否变化(需 Wireshark 解密) - 旧票据是否仍能复用:停用最新密钥后,确认之前建立的连接仍能
Reused, TLS - 检查 Nginx 错误日志:若密钥格式错误或路径不对,会报
SSL_CTX_set_ticket_keys() failed











