zoukankan      html  css  js  c++  java
  • [tls][https][nginx] https的client session cache与session ticket机制分析

    more title

    tls的客户端会话恢复与会话票证机制分析

    golang fasthttp库关于会话恢复与会话票证的源码分析

    前言

    https握一次手是很艰辛的,计算量很大。所以如果连续两次短连接通信的话,完全可以

    复用上一次的会话。这样可以压缩通信,节省计算。

    TLS提供了两个机制来做这个事。分别是

    session cache(会话缓存,会话恢复)

    session ticket (会话票证)

    此二者,除了达到的结果一样以为,在机制上并没有什么其他关系。

     [classic_tong @ https://www.cnblogs.com/hugetong/p/12192587.html]

    结果一致

    先来看,成功的恢复了上一次的会话,或者说成功复用的情况是啥样的。

    在server发给client的包里,如下截图中体现的特征,可以说明,两端支持了session cache或者session ticket:

    Session Cache分析

    nginx可以通过如下配置,打开session cache

    Syntax:    ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
    Default:    
    ssl_session_cache none;
    Context:    http, server

    见:https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache

    开session cache而不开session ticket的client模拟,这个事用浏览器,curl,wget都不是很好模拟。笔者千辛万苦终于发现openssl

    准备了这个场景,构建如下:

    openssl s_client -connect test1.www.local:443 --reconnect -no_ticket -CAfile ~/Keys/https/root/root.cer

    主要是reconnect参数,他会连发5次,专门用来测session cache。

    协议细节

    这里有个关键信息,叫session id,用来代表tls会话。分别位于client hello与server hello里。二者相同时,说明通过协商恢复了旧的session。

    二者不同时,server hello中ID,作为本次会话的代表。(如下图,是我从实验中的首次TLS会话的serverhello)

    当client渴望恢复会话时,它会把本地保存的上次的会话ID在 client hello中发给server。(如下图,为紧接着上图的第二次TLS会话)

    当server收到了session id非空的clienthello时,会知道client希望进行会话恢复。如果他在本地找到了这个会话,便会用相同的ID进行

    serverhello回复,否则便生成新的会话,自然也使用新的session id。(如下图,是成功进行了会话恢复的情况)

     [classic_tong @ https://www.cnblogs.com/hugetong/p/12192587.html]

    Session Ticket分析

    session ticket相比于前者,是一种新的会话恢复机制。它的思想在于服务器去处它的所有会话数据(状态)并进行加密,再以票证的方式发回

    客户端。在接下来的连接中,客户端将票证提交回服务器,由服务器检查票证的完整性,解密其内容,再使用其中的信息恢复会哈。这种方式

    有可能使扩展服务器集群更为简单,因为如果不使用这种方式,就需要在服务集群的各个节点之间同步会话。(摘自<https权威指南>)

    不过,需要额外提及的是。session ticket的引入,破坏了TLS的安全模型。(略)

    配置

    nginx的配置方法。默认就是开的,其实不用配

    Syntax:    ssl_session_tickets on | off;
    Default:    
    ssl_session_tickets on;
    Context:    http, server
    This directive appeared in version 1.5.9.

    client,我用的是笔者fork的一个github项目,gobench:https://github.com/tony-caotong/gobench

    它背后使用的是golang的fasthttp库,后面会祥述。https://github.com/valyala/fasthttp

    协议细节

    RFC:https://tools.ietf.org/html/rfc5077

    client

    当client支持session ticket的时候,在client hello中会包含一个叫做session_ticket的扩展字段。当本地没有需要恢复的ticket,但是渴望与server

    达成一致对ticket进行支持时,如图。

     当本地,有需要恢复的ticket时,session_ticket 字段会存这需要恢复的ticket。如图:

     当client不支持session ticket时,client hello中,将不包括session ticket数据段。

    server

    server收到ticket的请求后,如果是一个空的ticket字段。server也会回复一个空的session ticket字段,表明它

    即将发起一个新的session ticket握手,并随后发送NewSessionTIcket报文。

    about session id

    ticker启用的前提下,client会在client hello里会带上一个session id。如果serverhello回复了同样的session

    id,说明server接受了这个ticket,并且同样恢复。如果serverhello回复了一个新的session id。说明server

    拒绝了client的ticket,并将发起一个新的ticket。

    也是就是说,成功恢复的链接,client与server的两个session id相同。

    more

    关于gobench,关于fasthttp,关于golang tls

    之所以分析了以上内容与机制,主要是因为fasthttp(golang tls)的实现中,将ticket与cache的耦合在了一起。

    golang的api不能配置出一种场景:ticket关,但是cache开。(也可能不是这一点,是我不会用,其实我几乎不会golang)所幸用上文的openssl命令可以弥补。

    当关闭ticket的时候,cache功能也失效了。

    主要因为在这个函数里:crypto/tls/handshake_client.go::loadSession(),有这样的一行判断。

     

    [classic_tong @ https://www.cnblogs.com/hugetong/p/12192587.html]

  • 相关阅读:
    TDateTime 的相关用法
    Delphi 2005 之后的版本如何装组件
    (收藏)《博客园精华集》分类索引
    用 IIS 7、ARR 與 Velocity 建设高性能的大型网站
    异常处理准则
    Linq之动态排序(字符传入)
    用存储过程构造一个虚拟日期表发现的趣事
    Linq to SQL 加注Data Annotation在 Asp.Net MVC2中的应用
    .net framework加密方法
    SQL Server到Oracle连接服务器
  • 原文地址:https://www.cnblogs.com/hugetong/p/12192587.html
Copyright © 2011-2022 走看看