SSL会话票据安全复用需配置多个48字节二进制密钥文件,新密钥置首行用于加密,全部密钥均可解密;密钥须用openssl rand 48生成、严格48字节、权限400;Nginx按配置顺序加载,推荐保留2–3个,轮换时仅新增不删除旧密钥,保留时间≥票据有效期(建议24小时);通过定时脚本实现原子性轮转,并用openssl s_client验证复用效果。

要让 ssl_session_tickets 真正安全又稳定复用,核心不是“启用就完事”,而是用一组受控轮换的 48 字节二进制密钥文件,新票据用最新密钥加密,旧票据仍能被历史密钥解密——Nginx 原生支持这种多密钥机制,关键在配置顺序和更新节奏。
生成合规的 48 字节二进制密钥文件
每个密钥必须是严格 48 字节原始二进制,用于 AES-128-CBC 加密 + HMAC-SHA256 验证。不能是文本、hex 或 base64。
- 用 OpenSSL 一次性生成:
openssl rand 48 > /etc/nginx/ticket.key.v$(date +%Y%m%d) - 验证长度:
ls -l /etc/nginx/ticket.key.v20260510应显示 48 - 禁止用编辑器打开或保存,避免换行/编码污染;可用
xxd -l 16确认内容为纯二进制 - 权限设为
400,属主为 Nginx 运行用户(如www-data)
在 Nginx 配置中按优先级顺序加载多个密钥
Nginx 按配置出现顺序使用密钥:第一行用于加密新票据,所有行都可用于解密入站票据。最多支持 10 个,推荐保留最近 2–3 个。
审查 Remix v2 代码中的 v1 形态 meta 导出(v2 中为破坏性变更),cookie 安全漏洞(httpOnly、secure、密钥轮换),认证门位于错误层级,以及其他
- 示例配置(放在
http或server块中):ssl_session_tickets on;<br>ssl_session_ticket_key /etc/nginx/ticket.key.v20260510;<br>ssl_session_ticket_key /etc/nginx/ticket.key.v20260410;<br>ssl_session_ticket_key /etc/nginx/ticket.key.v20260310;
- 每次轮换只需把新密钥加在最前面,不删旧的——确保客户端携带的旧票据还能被解密
- 密钥保留时间应 ≥ 最大票据有效期(OpenSSL 默认约 4 小时),建议至少保留 24 小时,覆盖滚动发布与意外重启
通过 cron + 脚本实现定期自动轮转
没有内置自动调度,但可通过定时脚本可靠实现,重点在于原子性与容错。
- 设置每月 1 日凌晨 2 点执行:
0 2 1 * * root /usr/local/bin/rotate-ticket-key.sh - 脚本内先生成新密钥文件,再用
sed -i '1i\ssl_session_ticket_key /etc/nginx/ticket.key.v'"$(date +%Y%m%d)"';' /etc/nginx/conf.d/ssl.conf插入首行 - 加入校验:检查新密钥是否为 48 字节、文件是否存在、Nginx 配置语法是否正确(
nginx -t) - 仅当全部校验通过后才执行
nginx -s reload;失败则发告警,不中断服务
验证票据是否生效且轮转正常
光配对不等于跑通,需端到端确认:
- 用
openssl s_client -connect example.com:443 -servername example.com -reconnect 2>/dev/null | grep "Reused, TLS"查看是否复用 - 对比两次连接的
Session-ID字段:应为空,这是票据模式的标志 - 检查 Nginx error log 是否有
SSL_do_handshake() failed或密钥读取失败提示 - 轮转后观察客户端是否仍能复用前几天建立的连接(说明旧密钥仍在列表中且有效)










