nginx中session ticket重用Session提高https性能分析

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 使用session ticket机制可以提高ssl握手的效率,并节约有效的服务器计算资源

原创文章:来自nginx中session ticket重用Session提高https性能分析

https会话建立初次使用session ticket的SSL握手流程如下:

     Client                                               Server

     ClientHello
    (empty SessionTicket extension)-------->
                                                     ServerHello
                                 (empty SessionTicket extension)
                                                    Certificate*
                                              ServerKeyExchange*
                                             CertificateRequest*
                                  <--------      ServerHelloDone
     Certificate*
     ClientKeyExchange
     CertificateVerify*
     [ChangeCipherSpec]
     Finished                     -------->
                                                NewSessionTicket
                                              [ChangeCipherSpec]
                                  <--------             Finished
     Application Data             <------->     Application Data

Figure 1: Message Flow for Full Handshake Issuing New Session Ticket

If the server successfully verifies the client's ticket, then it MAY renew the ticket by including a NewSessionTicket handshake message after the ServerHello in the abbreviated handshake. The client should start using the new ticket as soon as possible after it verifies the server's Finished message for new connections. Note that since the updated ticket is issued before the handshake completes, it is possible that the client may not put the new ticket into use before it initiates new connections. The server MUST NOT assume that the client actually received the updated ticket until it successfully verifies the client's Finished message.

而session重用时SSL握手简化为如下步骤:

   Client                                                Server
     ClientHello
     (SessionTicket extension)      -------->
                                                      ServerHello
                                  (empty SessionTicket extension)
                                                 NewSessionTicket
                                               [ChangeCipherSpec]
                                   <--------             Finished
     [ChangeCipherSpec]
     Finished                      -------->
     Application Data              <------->     Application Data

Figure 2: Message Flow for Abbreviated Handshake Using New Session
                              Ticket

使用session ticket机制可以提高ssl握手的效率,并节约有效的服务器计算资源.(另外一种是使用session cache)

nginx中使用 ssl_session_ticket_key file; 指令来配置用于加密或解密SSL session_ticket的密钥, 如果用了多个指令文件,则仅第一个指令文件中的密钥用来加密; 其它的密钥文件,并且第一个密钥文件都可以用做解密.

一般nginx.conf 中配置如下


ssl_session_ticket_key encode_decode.key;
ssl_session_ticket_key decode.key;

encode_decode.key用于加密ticket 也用于解密ticket

decode.key用于解密曾用decode.key加密过的ticket;

如果nginx.conf中没有配置key文件,则openssl默认会生成随机数的key,生成的时机: (keys are randomly generated when SSL context is initialized).

session ticket机制综述

The ticket mechanism is a TLS extension. The client can advertise its support by sending an empty “Session Ticket” extension in the “Client Hello” message. The server will answer with an empty “Session Ticket” extension in its “Server Hello” message if it supports it. If one of them does not support this extension, they can fallback to the session identifier mechanism built into SSL.

session tickets are an optional TLS extension and therefore, the support is not as widespread as for session identifiers. Support for tickets was added in OpenSSL 0.9.8f (October 2007)

TLS 和session ticket机制相关的RFC文档

  • 握手阶段最后一条由server发出的NewSessionTicket消息的格式(RFC 5077)如下, 可以是全握手时发出,也可以是简要握手时发出


NewSessionTicket消息的格式:
    struct {
      uint32 ticket_lifetime_hint;  
      opaque ticket<0..2^16-1>;
  } NewSessionTicket;

ticket_lifetime_hint: The value indicates the lifetime in seconds as a 32-bit unsigned integer in network byte order relative to when the ticket is received.

RFC5077推荐的ticket消息格式如下:

The ticket is structured as follows:

  struct {
      opaque key_name[16];
      opaque iv[16];
      opaque encrypted_state<0..2^16-1>;
      opaque mac[32];
  } ticket;

followed by the length of the encrypted_state field (2 octets) and its contents (variable length).

上述结构encrypted_state未加密明文内容如下:

struct {
      ProtocolVersion protocol_version;
      CipherSuite cipher_suite;
      CompressionMethod compression_method;
      opaque master_secret[48];
      ClientIdentity client_identity;
      uint32 timestamp;
  } StatePlaintext;

  enum {
     anonymous(0),
     certificate_based(1),
     psk(2)
 } ClientAuthenticationType;

  struct {
      ClientAuthenticationType client_authentication_type;
      select (ClientAuthenticationType) {
          case anonymous: struct {};
          case certificate_based:
              ASN.1Cert certificate_list<0..2^24-1>;
          case psk:
              opaque psk_identity<0..2^16-1>;   /* from [RFC4279] */
      };
   } ClientIdentity;

注: 而在openssl 的实现中 session 共享的信息用结构体ssl_session_st来表示
或SSL_SESSION_ASN1, 使用i2d_SSL_SESSION()函数生成需要加密的ticket.

问题1 如果session ID 和session ticket都在client hello提供时以那个为准起作用?

答案: 以session ticket为准.详细的解释如下,

rfc5077 3.4. Interaction with TLS Session ID 做了说明如下:

If a ticket is presented by the client, the server MUST NOT attempt to use the
Session ID in the ClientHello for stateful session resumption.

openssl代码中利用session ticket或session ID恢复session的处理实现逻辑:

ssl3_get_client_hello(SSL *s) -->
根据sessionID或ticket查找session的函数 ssl_get_prev_session()-->
根据ticket解密session信息tls1_process_ticket()-->
利用全局ctx ticket_key或应用层即nginx tlsext_ticket_key_cb回调解密 tls_decrypt_ticket()

如果上述解ticket失败或没有ticket则调用lh_SSL_SESSION_retrieve() 根据session id取cache中的信息恢复

如果openssl本身cache中没找到则根据session id从应用层nginx回调函数get_session_cb()中查找;并SSL_CTX_add_session(s->session_ctx, ret);//将外部的cache加入到openssl中

目录
相关文章
|
16天前
|
Web App开发 算法 应用服务中间件
nginx开启局域网https访问
【10月更文挑战第22天】为了调试WebRTC功能,需要在局域网内搭建HTTPS协议。具体步骤包括:在已部署Nginx和安装OpenSSL的环境中生成私钥、证书签名请求和自签名证书;将生成的文件放置到Nginx的证书目录并修改Nginx配置文件,最后重启Nginx服务。注意,自签名证书不受第三方机构认可,如需正式使用,需向CA申请签名。
|
1月前
|
安全 应用服务中间件 Shell
nginx配置https的ssl证书和域名
nginx配置https的ssl证书和域名
|
1月前
|
Docker 容器
docker nginx-proxy 添加自定义https网站
docker nginx-proxy 添加自定义https网站
39 4
|
3月前
|
缓存 算法 应用服务中间件
nginx搭建https服务器
nginx搭建https服务器
|
6月前
|
安全 网络协议 应用服务中间件
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
|
5月前
|
网络协议 安全 应用服务中间件
阿里云 网站https设置 sll申请与nginx跳转配置
阿里云 网站https设置 sll申请与nginx跳转配置
197 0
|
6月前
|
缓存 应用服务中间件 网络安全
nginx 日志,压缩,https功能介绍
nginx 日志,压缩,https功能介绍
|
6月前
|
缓存 安全 应用服务中间件
蓝易云 - Nginx的HTTPS部署与安全性能优化教程
以上就是在Nginx上部署HTTPS并进行安全性能优化的基本步骤。需要注意的是,这些步骤可能会根据您的具体需求和环境有所不同。
56 0
|
6月前
|
Ubuntu 应用服务中间件 Linux
nginx 配置代理ip访问https的域名配置
nginx 配置代理ip访问https的域名配置
1199 2
|
6月前
|
应用服务中间件 网络安全 nginx
nginx配置https访问
nginx配置https访问
221 0