0
点赞
收藏
分享

微信扫一扫

Jmeter系列(5)线程数到底能设置多大

花明 03-01 08:30 阅读 4

目录

阅读姊妹篇:深入理解nginx的https alpn机制

1. 概述

  应用层协议协商Application-Layer Protocol Negotiation,简称ALPN)是一个传输层安全协议(TLS) 的扩展, ALPN 使得应用层可以协商在安全连接层之上使用什么协议, 避免了额外的往返通讯, 并且独立于应用层协议。 ALPN 用于 HTTP/2 连接, 和HTTP/1.x 相比, HTTP 2的使用增强了网页的压缩率减少了网络延时。 ALPN 和 HTTP/2 协议是伴随着 Google 开发 SPDY 协议出现的。

  nginx能够在一个ssl监听端口上同时提供http/1.1和http/2的服务,而http/2协议规定是必须基于tls安全通信协议的,因此,nginx在ssl握手过程中实现了ALPN的协议协商功能,能够自动完成和客户端的协议协商,从而根据客户端的协议支持能力提供http/1.1或者http/2的服务。

  本文基于nginx,对alpn的实现原理进行深入的分析。

2. alpn协议的简要理解

2.1 ssl的握手过程

在这里插入图片描述

  由上图可以看到,alpn的协商过程是在ssl握手的最早的两个阶段,即ClientHello和ServerHello中完成的,通过将应用层协议协商信息附加到ClientHello和ServerHello报文中完成的交互。

2.2 通过抓包看一下alpn的细节

  下面通过TLS v1.2握手协议来查看alpn的细节,对于TLS v1.3协议,在ServerHello响应的时候由于alpn部分的信息被加密,所以查看起来比较会麻烦。抓包通过wireshark来实现,通过以下命令来模拟http2的请求:

curl --http2 "https://www.test.com" -kv

  下到的报文如下:

  ClientHello报文:
在这里插入图片描述

  ServerHello报文:
在这里插入图片描述

  在ClientHello报文中可以看到application_layer_protocol_negotiation的信息,表明了客户端可以同时支持h2和http/1.1,而在ServerHello报文中也可以看到application_layer_protocol_negotiation的信息,表明服务器选择了h2协议作为应用层协议。

3. nginx源码分析

3.1 给ssl上下文设置alpn回调

   nginx在启动的时候,ngx_http_ssl_module模块在ngx_http_ssl_merge_srv_conf的时候,有以下这段代码对ssl的上下文进行初始化:

	/* 创建ssl上下文 */
	if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
   
        return NGX_CONF_ERROR;
    }

	/* 注册用于ssl上下文资源回收的回调函数
    cln = ngx_pool_cleanup_add(cf->pool, 0);
    if (cln == NULL) {
        ngx_ssl_cleanup_ctx(&conf->ssl);
        return NGX_CONF_ERROR;
    }

    cln->handler = ngx_ssl_cleanup_ctx;
    cln->data = &conf->ssl;

	/* 设置ClientHello消息回调 */
#if defined(T_INGRESS_SHARED_MEMORY_PB) && OPENSSL_VERSION_NUMBER >= 0x10101000L
    SSL_CTX_set_client_hello_cb(conf->ssl.ctx,
                                ngx_http_ssl_client_hello_callback, NULL);
#endif

	/* 设置SNI消息回调 */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

    if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
                                               ngx_http_ssl_servername)
        == 0)
    {
   
        ngx_log_error(NGX_LOG_WARN, cf->log, 0,
            "nginx was built with SNI support, however, now it is linked "
            "dynamically to an OpenSSL library which has no tlsext support, "
            "therefore SNI is not available");
    }

#endif

	/* 设置ALPN消息回调  */
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
    SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
#endif

   没错,最以上源码的最后部分,nginx向openssl底层库设置了alpn的回调函数ngx_http_ssl_alpn_select,以期待接收到从客户端发过来的ClientHello中分析出有alpn扩展信息的时候回调这个函数。

3.2 连接初始化

  在3.1节中所述的ssl上下文准备好以后,ssl连接当然是还没有建立的,只能说仍然只是停留在配置阶段,那么接下去可以想到客户端发起了tcp连接,nginx接受了这个连接,就需要开始对这个连接进行初始化,连接的初始化过程是由ngx_http_init_connection函数来完成的。那么如果开启了https,就会执行如下代码:

举报

相关推荐

0 条评论