会话门票
【Session tickets】
服务器会加密整个会话状态,并将其作为“票据”发送给客户端。在重新连接时,该状态会在初始连接中发送到服务器。这种机制避免了服务器端会话缓存的需求。如果服务器因为任何原因(无法解密、票据过旧等)不使用票据,它将创建一个新的会话并发送一个新的票据。更多信息请参见 RFC 5077。
【The servers encrypt the entire session state and send it to the client as a "ticket". When reconnecting, the state is sent to the server in the initial connection. This mechanism avoids the need for a server-side session cache. If the server doesn't use the ticket, for any reason (failure to decrypt it, it's too old, etc.), it will create a new session and send a new ticket. See RFC 5077 for more information.】
在使用 HTTPS 请求时,许多网络浏览器越来越普遍地支持使用会话票据进行恢复。
【Resumption using session tickets is becoming commonly supported by many web browsers when making HTTPS requests.】
对于 Node.js,客户端使用与会话票证恢复相同的 API 来进行会话标识符恢复。用于调试时,如果 tls.TLSSocket.getTLSTicket() 返回一个值,会话数据包含票证,否则它包含客户端会话状态。
【For Node.js, clients use the same APIs for resumption with session identifiers
as for resumption with session tickets. For debugging, if
tls.TLSSocket.getTLSTicket() returns a value, the session data contains a
ticket, otherwise it contains client-side session state.】
使用 TLSv1.3 时,请注意服务器可能会发送多个票证,从而导致多个 'session' 事件,更多信息请参见 'session'。
【With TLSv1.3, be aware that multiple tickets may be sent by the server,
resulting in multiple 'session' events, see 'session' for more
information.】
单进程服务器无需特定实现即可使用会话票据。要在服务器重启或负载均衡器之间使用会话票据,所有服务器必须拥有相同的票据密钥。内部有三个16字节的密钥,但 TLS API 为方便起见将它们作为一个48字节的缓冲区暴露出来。
【Single process servers need no specific implementation to use session tickets. To use session tickets across server restarts or load balancers, servers must all have the same ticket keys. There are three 16-byte keys internally, but the tls API exposes them as a single 48-byte buffer for convenience.】
可以通过在一个服务器实例上调用 server.getTicketKeys() 来获取票据密钥,然后分发它们,但更合理的方法是安全地生成 48 字节的随机数据,并使用 tls.createServer() 的 ticketKeys 选项来设置它们。密钥应定期重新生成,并且可以使用 server.setTicketKeys() 重置服务器的密钥。
【It's possible to get the ticket keys by calling server.getTicketKeys() on
one server instance and then distribute them, but it is more reasonable to
securely generate 48 bytes of secure random data and set them with the
ticketKeys option of tls.createServer(). The keys should be regularly
regenerated and server's keys can be reset with
server.setTicketKeys().】
会话票据密钥是加密密钥,必须安全存储。在 TLS 1.2 及以下版本中,如果这些密钥被泄露,使用这些密钥加密的所有会话都可以被解密。它们不应存储在磁盘上,并且应定期重新生成。
【Session ticket keys are cryptographic keys, and they must be stored securely. With TLS 1.2 and below, if they are compromised all sessions that used tickets encrypted with them can be decrypted. They should not be stored on disk, and they should be regenerated regularly.】
如果客户端声明支持票据,服务器将会发送票据。服务器可以通过在 secureOptions 中提供 require('node:constants').SSL_OP_NO_TICKET 来禁用票据。
【If clients advertise support for tickets, the server will send them. The
server can disable tickets by supplying
require('node:constants').SSL_OP_NO_TICKET in secureOptions.】
会话标识符和会话票据都会超时,导致服务器创建新的会话。超时时间可以通过 tls.createServer() 的 sessionTimeout 选项进行配置。
【Both session identifiers and session tickets timeout, causing the server to
create new sessions. The timeout can be configured with the sessionTimeout
option of tls.createServer().】
对于所有机制,当会话恢复失败时,服务器将创建新的会话。由于会话恢复失败不会导致 TLS/HTTPS 连接失败,因此很容易忽略不必要的低效 TLS 性能。可以使用 OpenSSL 命令行工具验证服务器是否正在恢复会话。例如,可以使用 openssl s_client 的 -reconnect 选项:
【For all the mechanisms, when resumption fails, servers will create new sessions.
Since failing to resume the session does not cause TLS/HTTPS connection
failures, it is easy to not notice unnecessarily poor TLS performance. The
OpenSSL CLI can be used to verify that servers are resuming sessions. Use the
-reconnect option to openssl s_client, for example:】
$ openssl s_client -connect localhost:443 -reconnect 阅读调试输出。第一个连接应该显示“新建”,例如:
【Read through the debug output. The first connection should say "New", for example:】
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256 后续连接应显示“已重用”,例如:
【Subsequent connections should say "Reused", for example:】
Reused, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256