Nginx SSL session ticket 密钥轮换需外部脚本+定时任务+精准 reload 实现:用 openssl rand 48 生成严格 48 字节二进制密钥,权限 400,配置中按时间倒序排列,新密钥置顶,旧密钥保留至少 2–3 个,cron 每月 1 日执行生成、插入、校验、reload 和清理。

开启 ssl_session_ticket_key 的定期自动轮换,不是简单改个配置就能“自动”生效——Nginx 本身不生成、不调度、不清理密钥,它只按配置顺序加载已存在的二进制文件。真正的自动轮换,是靠外部脚本+定时任务+精准 reload 实现的闭环流程。
密钥文件必须严格合规
每一份密钥都是安全复用的根基,出错会导致票据解密失败、连接降级甚至中断:
- 必须用
openssl rand 48 > /etc/nginx/ticket.key.v$(date +%Y%m%d)生成,确保原始二进制、恰好 48 字节 - 禁止用文本编辑器打开或保存,哪怕只加一个换行也会破坏结构
- 验证命令:
ls -l /etc/nginx/ticket.key.v20260509看大小是否为 48;xxd -l 8 /etc/nginx/ticket.key.v20260509确认是乱码二进制 - 权限设为
400,属主为 Nginx 运行用户(如www-data或nginx)
配置中多密钥按时间倒序排列
Nginx 按配置顺序从上到下读取 ssl_session_ticket_key 行:第一行用于加密新票据,所有行都可用于解密旧票据。因此最新密钥必须置顶,旧密钥保留在下方:
由 ReMe 驱动的记忆管理系统,支持跨会话记忆持久化、自动应用用户偏好以及智能上下文压缩...
- 当前主密钥(最新):
ssl_session_ticket_key /etc/nginx/ticket.key.v20260509; - 上期密钥(仍需保留):
ssl_session_ticket_key /etc/nginx/ticket.key.v20260401; - 再上期密钥(建议至少保留 2–3 个):
ssl_session_ticket_key /etc/nginx/ticket.key.v20260301; - 新增密钥时,只插入首行,绝不删除或覆盖已有行
用 cron + shell 脚本实现准自动轮转
每月 1 日凌晨 2 点执行轮转是最常见且稳妥的节奏(兼顾安全性与运维可控性):
- 在
/etc/cron.d/rotate-ticket中添加:0 2 1 * * root /usr/local/bin/rotate-ticket-key.sh - 脚本内依次完成:生成新密钥 → 插入配置首行(用
sed -i '1i\ssl_session_ticket_key ...')→nginx -t校验语法 →nginx -s reload - 加入清理逻辑:用
find /etc/nginx -name "ticket.key.*" -mtime +72 -delete自动清除 72 小时前的密钥文件 - 失败时发告警(如写入 syslog 或调用 webhook),不 reload,不中断服务
验证轮转是否真正生效
配完不等于跑通,需端到端确认:
- 用
openssl s_client -connect example.com:443 -servername example.com -reconnect 2>/dev/null | grep "Reused"查看是否复用成功 - 对比两次连接输出中的
Session-ID:应为空(说明走的是票据模式,而非传统 session cache) - 检查
error.log是否有SSL_do_handshake() failed或failed to load ticket key类报错 - 轮转后,让客户端保持连接数小时再重连,确认旧票据仍能被解密复用(证明旧密钥仍在列表中且有效)










