diff options
author | Andrey Suvorov <a.suvorov@f5.com> | 2021-07-21 15:22:52 -0700 |
---|---|---|
committer | Andrey Suvorov <a.suvorov@f5.com> | 2021-07-21 15:22:52 -0700 |
commit | c37ff7ed0ed06b0e928efdb217a8999ff3ff7f50 (patch) | |
tree | fd15b76217595c36dfedbd25ccc0d69a7547085f | |
parent | 1f2ba4dca8c67442e19367ac7f1f96dbff6457ff (diff) | |
download | unit-c37ff7ed0ed06b0e928efdb217a8999ff3ff7f50.tar.gz unit-c37ff7ed0ed06b0e928efdb217a8999ff3ff7f50.tar.bz2 |
Enabling configure TLS sessions.
To support TLS sessions, Unit uses the OpenSSL built-in session cache; the
cache_size option defines the number sessions to store. To disable the feather,
the option must be zero.
-rw-r--r-- | docs/changes.xml | 6 | ||||
-rw-r--r-- | src/nxt_conf_validation.c | 59 | ||||
-rw-r--r-- | src/nxt_openssl.c | 36 | ||||
-rw-r--r-- | src/nxt_router.c | 48 | ||||
-rw-r--r-- | src/nxt_tls.h | 15 |
5 files changed, 142 insertions, 22 deletions
diff --git a/docs/changes.xml b/docs/changes.xml index 68db823d..2aa9bb65 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -33,6 +33,12 @@ NGINX Unit updated to 1.25.0. <change type="feature"> <para> +TLS sessions cache. +</para> +</change> + +<change type="feature"> +<para> process and thread lifecycle hooks in Ruby. </para> </change> diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index a16c955c..fd57a983 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -95,6 +95,10 @@ static nxt_int_t nxt_conf_vldt_object_conf_commands(nxt_conf_validation_t *vldt, #endif static nxt_int_t nxt_conf_vldt_certificate_element(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); +static nxt_int_t nxt_conf_vldt_tls_cache_size(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_tls_timeout(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); #endif static nxt_int_t nxt_conf_vldt_action(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); @@ -206,6 +210,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[]; #if (NXT_TLS) static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[]; +static nxt_conf_vldt_object_t nxt_conf_vldt_session_members[]; #endif static nxt_conf_vldt_object_t nxt_conf_vldt_match_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_python_target_members[]; @@ -378,11 +383,65 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[] = { .validator = nxt_conf_vldt_unsupported, .u.string = "conf_commands", #endif + }, { + .name = nxt_string("session"), + .type = NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_object, + .u.members = nxt_conf_vldt_session_members, }, NXT_CONF_VLDT_END }; + +static nxt_conf_vldt_object_t nxt_conf_vldt_session_members[] = { + { + .name = nxt_string("cache_size"), + .type = NXT_CONF_VLDT_INTEGER, + .validator = nxt_conf_vldt_tls_cache_size, + }, { + .name = nxt_string("timeout"), + .type = NXT_CONF_VLDT_INTEGER, + .validator = nxt_conf_vldt_tls_timeout, + }, + + NXT_CONF_VLDT_END +}; + + +static nxt_int_t +nxt_conf_vldt_tls_cache_size(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + int64_t cache_size; + + cache_size = nxt_conf_get_number(value); + + if (cache_size < 0) { + return nxt_conf_vldt_error(vldt, "The \"cache_size\" number must not " + "be negative."); + } + + return NXT_OK; +} + + +static nxt_int_t +nxt_conf_vldt_tls_timeout(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + int64_t timeout; + + timeout = nxt_conf_get_number(value); + + if (timeout <= 0) { + return nxt_conf_vldt_error(vldt, "The \"timeout\" number must be " + "greater than zero."); + } + + return NXT_OK; +} + #endif diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 2fd5d1bf..3b5d4fda 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -42,15 +42,16 @@ static void nxt_openssl_lock(int mode, int type, const char *file, int line); static unsigned long nxt_openssl_thread_id(void); static void nxt_openssl_locks_free(void); #endif -static nxt_int_t nxt_openssl_server_init(nxt_task_t *task, - nxt_tls_conf_t *conf, nxt_mp_t *mp, nxt_conf_value_t *conf_cmds, - nxt_bool_t last); +static nxt_int_t nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp, + nxt_tls_init_t *tls_init, nxt_bool_t last); static nxt_int_t nxt_openssl_chain_file(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_conf_t *conf, nxt_mp_t *mp, nxt_bool_t single); #if (NXT_HAVE_OPENSSL_CONF_CMD) static nxt_int_t nxt_ssl_conf_commands(nxt_task_t *task, SSL_CTX *ctx, nxt_conf_value_t *value, nxt_mp_t *mp); #endif +static void nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, + time_t timeout); static nxt_uint_t nxt_openssl_cert_get_names(nxt_task_t *task, X509 *cert, nxt_tls_conf_t *conf, nxt_mp_t *mp); static nxt_int_t nxt_openssl_bundle_hash_test(nxt_lvlhsh_query_t *lhq, @@ -265,11 +266,12 @@ nxt_openssl_locks_free(void) static nxt_int_t -nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf, - nxt_mp_t *mp, nxt_conf_value_t *conf_cmds, nxt_bool_t last) +nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp, + nxt_tls_init_t *tls_init, nxt_bool_t last) { SSL_CTX *ctx; const char *ciphers, *ca_certificate; + nxt_tls_conf_t *conf; STACK_OF(X509_NAME) *list; nxt_tls_bundle_conf_t *bundle; @@ -279,6 +281,8 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf, return NXT_ERROR; } + conf = tls_init->conf; + bundle = conf->bundle; nxt_assert(bundle != NULL); @@ -337,13 +341,15 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf, } #if (NXT_HAVE_OPENSSL_CONF_CMD) - if (conf_cmds != NULL - && nxt_ssl_conf_commands(task, ctx, conf_cmds, mp) != NXT_OK) + if (tls_init->conf_cmds != NULL + && nxt_ssl_conf_commands(task, ctx, tls_init->conf_cmds, mp) != NXT_OK) { goto fail; } #endif + nxt_ssl_session_cache(ctx, tls_init->cache_size, tls_init->timeout); + SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); if (conf->ca_certificate != NULL) { @@ -582,6 +588,22 @@ fail: #endif +static void +nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, time_t timeout) +{ + if (cache_size == 0) { + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + return; + } + + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); + + SSL_CTX_sess_set_cache_size(ctx, cache_size); + + SSL_CTX_set_timeout(ctx, (long) timeout); +} + + static nxt_uint_t nxt_openssl_cert_get_names(nxt_task_t *task, X509 *cert, nxt_tls_conf_t *conf, nxt_mp_t *mp) diff --git a/src/nxt_router.c b/src/nxt_router.c index 409f88a1..1156edb8 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -44,10 +44,10 @@ typedef struct { nxt_str_t name; nxt_socket_conf_t *socket_conf; nxt_router_temp_conf_t *temp_conf; - nxt_conf_value_t *conf_cmds; + nxt_tls_init_t *tls_init; nxt_bool_t last; - nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ + nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ } nxt_router_tlssock_t; #endif @@ -123,8 +123,8 @@ static void nxt_router_listen_socket_error(nxt_task_t *task, static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, - nxt_conf_value_t *value, nxt_socket_conf_t *skcf, - nxt_conf_value_t * conf_cmds, nxt_bool_t last); + nxt_conf_value_t *value, nxt_socket_conf_t *skcf, nxt_tls_init_t *tls_init, + nxt_bool_t last); #endif static void nxt_router_app_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_app_t *app); @@ -1341,7 +1341,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_t *router; nxt_app_joint_t *app_joint; #if (NXT_TLS) - nxt_conf_value_t *certificate, *conf_cmds; + nxt_tls_init_t *tls_init; + nxt_conf_value_t *certificate; #endif nxt_conf_value_t *conf, *http, *value, *websocket; nxt_conf_value_t *applications, *application; @@ -1363,6 +1364,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, #if (NXT_TLS) static nxt_str_t certificate_path = nxt_string("/tls/certificate"); static nxt_str_t conf_commands_path = nxt_string("/tls/conf_commands"); + static nxt_str_t conf_cache_path = nxt_string("/tls/session/cache_size"); + static nxt_str_t conf_timeout_path = nxt_string("/tls/session/timeout"); #endif static nxt_str_t static_path = nxt_string("/settings/http/static"); static nxt_str_t websocket_path = nxt_string("/settings/http/websocket"); @@ -1741,7 +1744,26 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, certificate = nxt_conf_get_path(listener, &certificate_path); if (certificate != NULL) { - conf_cmds = nxt_conf_get_path(listener, &conf_commands_path); + tls_init = nxt_mp_get(tmcf->mem_pool, sizeof(nxt_tls_init_t)); + if (nxt_slow_path(tls_init == NULL)) { + return NXT_ERROR; + } + + tls_init->cache_size = 0; + tls_init->timeout = 300; + + value = nxt_conf_get_path(listener, &conf_cache_path); + if (value != NULL) { + tls_init->cache_size = nxt_conf_get_number(value); + } + + value = nxt_conf_get_path(listener, &conf_timeout_path); + if (value != NULL) { + tls_init->timeout = nxt_conf_get_number(value); + } + + tls_init->conf_cmds = nxt_conf_get_path(listener, + &conf_commands_path); if (nxt_conf_type(certificate) == NXT_CONF_ARRAY) { n = nxt_conf_array_elements_count(certificate); @@ -1752,7 +1774,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_assert(value != NULL); ret = nxt_router_conf_tls_insert(tmcf, value, skcf, - conf_cmds, i == 0); + tls_init, i == 0); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } @@ -1761,7 +1783,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } else { /* NXT_CONF_STRING */ ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf, - conf_cmds, 1); + tls_init, 1); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } @@ -1856,7 +1878,7 @@ fail: static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *value, nxt_socket_conf_t *skcf, - nxt_conf_value_t *conf_cmds, nxt_bool_t last) + nxt_tls_init_t *tls_init, nxt_bool_t last) { nxt_router_tlssock_t *tls; @@ -1865,8 +1887,8 @@ nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, return NXT_ERROR; } + tls->tls_init = tls_init; tls->socket_conf = skcf; - tls->conf_cmds = conf_cmds; tls->temp_conf = tmcf; tls->last = last; nxt_conf_get_string(value, &tls->name); @@ -2467,6 +2489,8 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, tlscf = tls->socket_conf->tls; } + tls->tls_init->conf = tlscf; + bundle = nxt_mp_get(mp, sizeof(nxt_tls_bundle_conf_t)); if (nxt_slow_path(bundle == NULL)) { goto fail; @@ -2480,8 +2504,8 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, bundle->next = tlscf->bundle; tlscf->bundle = bundle; - ret = task->thread->runtime->tls->server_init(task, tlscf, mp, - tls->conf_cmds, tls->last); + ret = task->thread->runtime->tls->server_init(task, mp, tls->tls_init, + tls->last); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } diff --git a/src/nxt_tls.h b/src/nxt_tls.h index 63c49ee4..a92f1c21 100644 --- a/src/nxt_tls.h +++ b/src/nxt_tls.h @@ -28,14 +28,14 @@ typedef struct nxt_tls_conf_s nxt_tls_conf_t; typedef struct nxt_tls_bundle_conf_s nxt_tls_bundle_conf_t; +typedef struct nxt_tls_init_s nxt_tls_init_t; typedef struct { nxt_int_t (*library_init)(nxt_task_t *task); void (*library_free)(nxt_task_t *task); - nxt_int_t (*server_init)(nxt_task_t *task, - nxt_tls_conf_t *conf, nxt_mp_t *mp, - nxt_conf_value_t *conf_cmds, + nxt_int_t (*server_init)(nxt_task_t *task, nxt_mp_t *mp, + nxt_tls_init_t *tls_init, nxt_bool_t last); void (*server_free)(nxt_task_t *task, nxt_tls_conf_t *conf); @@ -78,6 +78,15 @@ struct nxt_tls_conf_s { }; +struct nxt_tls_init_s { + size_t cache_size; + nxt_time_t timeout; + nxt_conf_value_t *conf_cmds; + + nxt_tls_conf_t *conf; +}; + + #if (NXT_HAVE_OPENSSL) extern const nxt_tls_lib_t nxt_openssl_lib; |