天天看點

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

https會話建立初次使用session ticket的ssl握手流程如下:

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握手簡化為如下步驟:

使用session ticket機制可以提高ssl握手的效率,并節約有效的伺服器計算資源.(另外一種是使用session cache)

nginx中使用 ssl_session_ticket_key file; 指令來配置用于加密或解密ssl session_ticket的密鑰, 如果用了多個指令檔案,則僅第一個指令檔案中的密鑰用來加密; 其它的密鑰檔案,并且第一個密鑰檔案都可以用做解密.

一般nginx.conf 中配置如下

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

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

如果nginx.conf中沒有配置key檔案,則openssl預設會生成随機數的key,生成的時機: (keys are randomly generated when ssl context is initialized).

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 1.0 defined in [rfc2246]

tls 1.1 defined in [rfc4346]

tls 1.2 defined in [rfc5246]

rfc5077 transport layer security (tls) session resumption without server-side state january 2008 目前用的是rfc5077,取代rfc4507

sessionticket tls [rfc4507] 被rfc5077取代

extensions: extension definitions [rfc6066]

握手階段最後一條由server發出的newsessionticket消息的格式(rfc 5077)如下, 可以是全握手時發出,也可以是簡要握手時發出

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:

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

上述結構encrypted_state未加密明文内容如下:

注: 而在openssl 的實作中 session 共享的資訊用結構體ssl_session_st來表示

或ssl_session_asn1, 使用i2d_ssl_session()函數生成需要加密的ticket.

答案: 以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中

繼續閱讀