SSL_CTX_new()建立新的SSL上下文 将密码列表,会话缓存设置,回调,密钥和证书以及选项初始化为默认值,参数为加密协议(ssl/tls版本)例如:SSLv23_server_method。
大部分TLS连接都以handshake为开始,经过应用数据的交换,最后关闭会话。如果在第一次handshake之后(可能经历了应用数据的交换也可能没有)请求重新协商,
就会发起一次新的handshake,对新的安全参数达成一致。重协商的handshake的消息都是全部加密的,这与第一次handshake明显不同。
增加异步处理点:
重新协商握手阶段,ngx_ssl_async_process_fds
ngx_ssl_shutdown关闭ssl阶段, error阶段ngx_ssl_async_process_fds、SSL_free阶段增加ngx_del_async_conn(NGX_DISABLE_EVENT),
SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE阶段,增加ngx_ssl_async_process_fds然后(NGX_DISABLE_EVENT)。
增加事件SSL_ERROR_WANT_ASYNC增加ngx_ssl_async_process_fds,然后ngx_del_async_conn(c, NGX_DISABLE_EVENT)。
TLS重新协商攻击:OpenSSL-TLS重协商_Remy1119的博客-CSDN博客_ssl重协商
https://github.com/michaeljclark/async_tls_test/blob/master/src/openssl_async_echo_server.cc
nginx1.10.0比我们tengine多ngx_ssl_check_host处理,ngx_ssl_create部分nginx1.10.1和tengine有所不同,基本但流程一样,nginx多了
#ifdef SSL_MODE_NO_AUTO_CHAIN
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN);
#endif
event_openssl.h文件增加ngx_ssl_waiting_for_async声明为SSL_waiting_for_async,该函数在ngx_http_request.c文件调用。
event_openssl.h增加ngx_ssl_async_process_fds声明,函数实现在c文件。
http_ssl_module.c结构体ngx_http_ssl_commands增加asyn
nginx Ngx_connection.c http处理过程Nginx学习笔记(二) Nginx--connection&request-阿里云开发者社区
异步增加部分
ngx_event_openssl.c文件:
1、ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)函数
ngx_pcalloc创建ngx_ssl_connection_t *sc;
sc->connection = SSL_new(ssl->ctx);
SSL_set_fd(sc->connection, c->fd)将connection->fd设置为SSL SSL(加密)侧的in/out功能。fd通常是网络连接的套接字文件描述符。如果fd是非阻塞的,SSL也将具有非阻塞行为。
根据flags决定
SSL_set_connect_state(sc->connection) sets ssl to work in client mode.
SSL_set_accept_state(sc->connection) sets ssl to work in server mode.
把连接c以ngx_ssl_connection_index为索引,set到sc->connection中。
SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) is used to store application data at arg for idx into the ssl object.
把ssl连接保存c连接结构体中
c->ssl = sc;
增加ss->asynch保存到c里
+c->asynch = ssl->asynch;
2、增加ngx_ssl_async_process_fds(ngx_connection_t *c)ssl异步句柄处理
检查是否支持Async
SSL_get_changed_async_fds(ngx_connection_t *c)调用ssl获取异步句柄变化接口,得到ssl新增add和释放del的fd,相应的把这些fd从epoll驱动增加/删除,调用epoll_ctl。
3、ngx_ssl_handshake(ngx_connection_t *c)ngx的ssl交互函数
在调用SSL_do_handshake(c->ssl->connection)后增加
+if(c->asynch && ngx_ssl_async_process_fds(c) == 0) {
+ return NGX_ERROR;
+}asynch句柄为空,或不支持asyn,或获取句柄变化出错,返回error。
ngx_event_openssl.h ngx_ssl_t结构体增加成员
+ ngx_flag_t asynch;
增加ssl_waiting函数声明+#define ngx_ssl_waiting_for_async(c) SSL_waiting_for_async(c->ssl->connection)
增加+ngx_int_t ngx_ssl_async_process_fds(ngx_connection_t *c) ;
ngx_http_init_connection
ngx_http_upstream_check_broken_connection
发现connection error执行ngx_del_event(ev, event, 0)
+增加删除该connection异步处理
+#if (NGX_HTTP_SSL)
+ if (c->asynch && ngx_del_async_conn) {
+ if (c->num_async_fds) {
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
+ c->num_async_fds--;
+ }
+ }
+#endif
ngx_http_read_request_header读取处理请求头,增加asyn异步recv判断
+#if (NGX_HTTP_SSL)
+ if(c->asynch)
n = c->recv(c, r->header_in->last,
+ r->header_in->end - r->header_in->last);
+ else {
+#endif
keepalive_timeout可以在nginx.conf配置文件中,通过keepalive_timeout指令设置,默认情况下超时时间就是75秒。
如果超过这个时间都还没有收到来自客户端新的http请求,则会关闭这个tcp连接,keepalive功能也就结束了。
ngx_http_set_keepalive函数则是正式开始keepalive的处理,函数有点长,实现了pipeline长连接与普通长连接。先来看下pipeline的实现。
nginx长连接keepalive与pipeline_ApeLife的博客-CSDN博客
ngx_http_set_keepalive函数
增加等待asyn异步处理完毕函数
+#if (NGX_HTTP_SSL)
+ if ((c->asynch && !ngx_ssl_waiting_for_async(c)) || !c->asynch) {
+#endif
+ b = c->buffer;
在ngx_del_event(wev, NGX_WRITE_EVENT, 0) 前增加
+#if (NGX_HTTP_SSL)
+ if (c->asynch && ngx_del_async_conn) {
+ if (c->num_async_fds) {
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
+ c->num_async_fds--;
+ }
+ }
+#endif
在释放连接池前if (ngx_pfree(c->pool, b->start) == NGX_OK) 增加
+#if (NGX_HTTP_SSL)
+ if ((c->asynch && !ngx_ssl_waiting_for_async(c)) || !c->asynch) {
+#endif
ngx_http_ssl_module.h结构体ngx_http_ssl_srv_conf_t增加
+ngx_flag_t enable_asynch;
ngx_http_ssl_module.c
ngx_http_ssl_commands增加ssl异步command注册
{ ngx_string("ssl_asynch"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+ ngx_http_ssl_enable,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, enable_asynch),
+ NULL },
ngx_http_ssl_create_srv_conf函数增加
+ sscf->enable_asynch = NGX_CONF_UNSET;
+ if (conf->enable_asynch == NGX_CONF_UNSET) {
+ if (prev->enable_asynch == NGX_CONF_UNSET) {
+ conf->enable_asynch = 0;
+
+ } else {
+ conf->enable_asynch = prev->enable_asynch;
+ conf->file = prev->file;
+ conf->line = prev->line;
+ }
+ }
+
+ conf->ssl.asynch = conf->enable_asynch;
--with-openssl-async
ssl_async on
为了展示Tengine启用异步SSL/TLS的效果,需要OpenSSL在算法层提供支持异步的引擎模块
在OpenSSL 1.1.0之后的版本中,默认提供了名为'dasync'的参考异步引擎
在完成OpenSSL编译后,异步引擎'dasync'会以共享库'dasync.so'的形式出现在engines/
目录下,使用如下openssl.cnf配置文件中的配置可以使能'dasync'异步引擎用于RSA算法
openssl_conf = openssl_def
[openssl_def]
engines = engine_section
[engine_section]
dasync = dasync_section
[dasync_section]
engine_id = dasync
dynamic_path = /path/to/openssl/source/engines/dasync.so
default_algorithms = RSA