Nginx 在 HTTPS 场景中通过 ssl_session_tickets 参数决定是否向客户端发送 TLS 会话票据。这个参数表面上只是一个 on 或 off 的开关,背后却涉及 TLS 会话恢复机制、状态存储策略以及安全前向保密之间的平衡。理解它的作用,需要从 TLS 握手的基本流程开始。TLS 完整握手需要两次往返甚至更多,客户端与服务器交换随机数、证书、密钥参数等信息,完成证书校验和密钥协商后才能进入加密通信。

TLS 会话恢复与会话票据的工作机制
TLS 协议为了减少重复握手的开销,设计了两种会话恢复方式:会话标识(Session ID)和会话票据(Session Ticket)。会话标识由服务端生成一个短 ID 并保存对应的会话参数在本地内存或共享缓存中。客户端重连时在 ClientHello 中带上这个 ID,服务端根据 ID 查找缓存并直接恢复会话。这种方式要求服务端保存状态,当服务节点较多时,缓存无法同步就会导致恢复失败。
会话票据则采用无状态设计。首次握手成功后,服务端将当前会话参数(如主密钥、密码套件等)加密生成一段票据,通过 NewSessionTicket 消息发送给客户端。客户端将其保存,下次连接时在 ClientHello 的 session_ticket 扩展中携带该票据。服务端使用本地密钥解密并校验票据,如果有效即可直接恢复会话,不需要查找任何本地缓存。因此会话票据特别适合负载均衡和多节点集群,因为任意节点只要持有相同的票据密钥就能解密票据。
Nginx 中的 ssl_session_tickets 指令就是控制是否启用这种无状态会话票据机制。当该选项开启时,Nginx 会在握手完成后发送 NewSessionTicket;关闭时则不会发送,客户端只能依赖会话标识或者每次都执行完整握手。该参数从 Nginx 1.5.9 版本开始默认开启,之前的版本默认关闭。这也是很多老配置迁移后行为变化的原因之一。
Nginx 中 ssl_session_tickets 的配置与调优
该指令可出现在 http、server 级别,语法为 ssl_session_tickets on | off; 默认值为 on。如果希望完全禁用会话票据,可以在 server 块中显式设置 ssl_session_tickets off;。需要注意的是,关闭票据并不等于关闭会话恢复,Nginx 仍然可以通过 ssl_session_cache 使用会话标识方式恢复会话。
与票据机制相关的指令还有 ssl_session_ticket_key、ssl_session_timeout 和 ssl_session_cache。ssl_session_ticket_key 用于指定票据加密密钥文件,如果不设置,Nginx 会使用随机生成的密钥,但进程重启后该随机密钥会变化,导致之前签发的票据全部失效。对于需要多节点共享票据或重启后保持会话恢复的场景,建议显式配置一个固定的票据密钥文件,并保证权限安全。
下面是一个典型的 HTTPS 站点配置,展示了开启票据并指定固定密钥的写法:
server {
listen 443 ssl;
server_name ipipp.com;
ssl_certificate /etc/nginx/ssl/ipipp.com.crt;
ssl_certificate_key /etc/nginx/ssl/ipipp.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
}
如果将 ssl_session_tickets 改为 off,则配置会变成:
server {
listen 443 ssl;
server_name ipipp.com;
ssl_certificate /etc/nginx/ssl/ipipp.com.crt;
ssl_certificate_key /etc/nginx/ssl/ipipp.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
}
在这种配置下,客户端只能尝试使用会话标识恢复,如果服务端缓存中没有对应条目,就会回退到完整握手。对于单节点服务或启用了共享缓存的环境,这种方式仍然可以提供一定的恢复能力。
开启与关闭的性能和安全权衡
从性能角度看,开启会话票据可以显著降低重复连接的延迟和计算开销。完整 TLS 握手需要传输证书、执行非对称加密运算,而会话恢复只需要对称解密票据并重新导出密钥,通常能节省一个甚至两个往返时间。对于大量短连接请求、移动端弱网环境以及 CDN 边缘节点来说,开启票据带来的收益非常明显。压测数据中关闭票据后,HTTPS 建连的 QPS 可能下降百分之三十以上,CPU 使用率也会随之上升。
但从安全角度看,会话票据机制存在一定的前向保密削弱问题。如果票据加密密钥长期不变,攻击者一旦获取该密钥,就能解密之前捕获的票据并恢复历史会话。因此推荐的做法是定期轮换票据密钥,并且不要把票据密钥写入版本控制系统或配置文件中明文暴露。Nginx 支持通过 ssl_session_ticket_key 加载多个密钥文件,第一个文件用于签发新票据,其余文件用于解密旧票据,从而实现平滑轮换。
关闭 ssl_session_tickets 在安全性上更保守,它会强制服务端不签发任何无状态票据,从而减少密钥管理风险。但关闭后如果同时禁用了会话缓存,客户端每次连接都会执行完整握手,导致性能大幅下降。因此实践中很少完全关闭所有会话恢复手段,更多是根据业务安全等级决定取舍。例如金融、政务等高安全场景可能倾向于关闭票据,仅使用有状态的会话缓存并严格控制缓存生命周期;而电商、资讯等高并发场景则更偏向开启票据以降低延迟。
集群部署时还要考虑票据密钥的分发一致性。若多个 Nginx 实例的票据密钥不同,客户端访问不同节点时会恢复失败,退化为完整握手。此时可以将同一个 ticket.key 安全分发到所有节点,或者使用集中式配置管理工具统一管理。
如何验证 ssl_session_tickets 是否生效
验证方式主要有两种:使用 OpenSSL 命令行工具观察会话恢复情况,以及通过网络抓包检查 TLS 扩展。OpenSSL 提供了 -reconnect 参数,可以在同一进程中发起两次连接并报告会话是否被重用。以下命令可以测试目标站点的会话恢复表现:
openssl s_client -connect ipipp.com:443 -servername ipipp.com -tls1_2 -reconnect
输出中会包含两次握手的信息,如果第二次连接显示 Reused session-id 或类似会话恢复标记,说明会话恢复成功。需要注意的是,OpenSSL 客户端默认可能使用会话标识而不是票据,为了明确票据是否生效,可以结合抓包查看 ClientHello 中是否包含 session_ticket 扩展,以及服务端是否返回了 NewSessionTicket 消息。
使用 Wireshark 或 tshark 抓包时,可以在 TLS 协商阶段观察到 ClientHello 的扩展列表中包含一个类型为 35 的 Session Ticket 扩展。如果服务端开启票据,ServerHello 之后会跟随一条 NewSessionTicket 握手消息,内容是一段不可读的加密二进制数据;如果关闭,则不会出现该消息。通过这种方式能够准确判断配置是否真正下发到了运行中的 Nginx 进程。
常见误区与故障排查
一个常见误区是认为只要开启了 ssl_session_tickets,就一定能实现会话恢复。实际上如果客户端不支持该扩展,或者票据密钥缺失、损坏,协商过程可能静默回退到完整握手。另一个误区是混淆会话票据和会话缓存,前者无状态、客户端保存,后者有状态、服务端保存。两者可以同时启用,也可以只保留其中一个。
当发现重连性能没有提升时,可以从几个方面排查:确认客户端是否在两次连接中使用了相同的 TLS 版本和密码套件;检查 Nginx 错误日志中是否有票据解密失败记录;确认多个节点的 ssl_session_ticket_key 是否一致;以及确认客户端是否真正发送了 session_ticket 扩展。有的代理或抓包工具会剥离该扩展,导致恢复无法使用。
此外,票据的有效期受 ssl_session_timeout 控制,默认 5 分钟,过期后客户端会重新进行完整握手。如果需要更长时间的会话保持,可以适当调大该值,但要与安全策略匹配。总之,ssl_session_tickets 这个开关的使用需要结合业务模型、安全要求和部署架构综合考虑,没有绝对的最佳答案。
Nginx ssl_session_ticketsTLS会话恢复会话票据修改时间:2026-10-04 19:48:11