From: Artem Boldariev Date: Tue, 21 Sep 2021 11:09:56 +0000 (+0300) Subject: Add "session-tickets" options to the "tls" clause X-Git-Tag: v9.17.19~17^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c759f25c7be641c0c666fd44d3f75283e99da1f6;p=thirdparty%2Fbind9.git Add "session-tickets" options to the "tls" clause This commit adds the ability to enable or disable stateless TLS session resumption tickets (see RFC5077). Having this ability is twofold. Firstly, these tickets are encrypted by the server, and the algorithm might be weaker than the algorithm negotiated during the TLS session establishment (it is in general the case for TLSv1.2, but the generic principle applies to TLSv1.3 as well, despite it having better ciphers for session tickets). Thus, they might compromise Perfect Forward Secrecy. Secondly, disabling it might be necessary if the same TLS key/cert pair is supposed to be used by multiple servers to achieve, e.g., load balancing because the session ticket by default gets generated in runtime, while to achieve successful session resumption ability, in this case, would have required using a shared key. The proper alternative to having the ability to disable stateless TLS session resumption tickets is to implement a proper session tickets key rollover mechanism so that key rotation might be performed often (e.g. once an hour) to not compromise forward secrecy while retaining the associated performance benefits. That is much more work, though. On the other hand, having the ability to disable session tickets allows having a deployable configuration right now in the cases when either forward secrecy is wanted or sharing the TLS key/cert pair between multiple servers is needed (or both). --- diff --git a/bin/named/named.conf.rst b/bin/named/named.conf.rst index ff9e7de0f88..7274c2044ab 100644 --- a/bin/named/named.conf.rst +++ b/bin/named/named.conf.rst @@ -569,6 +569,7 @@ TLS key-file quoted_string; prefer-server-ciphers boolean; protocols { string; ... }; + session-tickets boolean; }; TRUST-ANCHORS diff --git a/bin/named/server.c b/bin/named/server.c index 3c3ebd7b483..e9d3bdc59e7 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -11027,6 +11027,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, *ciphers = NULL; bool tls_prefer_server_ciphers = false, tls_prefer_server_ciphers_set = false; + bool tls_session_tickets = false, tls_session_tickets_set = false; bool do_tls = false, no_tls = false, http = false; ns_listenelt_t *delt = NULL; uint32_t tls_protos = 0; @@ -11052,6 +11053,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, const cfg_obj_t *tls_proto_list = NULL; const cfg_obj_t *ciphers_obj = NULL; const cfg_obj_t *prefer_server_ciphers_obj = NULL; + const cfg_obj_t *session_tickets_obj = NULL; do_tls = true; @@ -11109,6 +11111,14 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, prefer_server_ciphers_obj); tls_prefer_server_ciphers_set = true; } + + if (cfg_map_get(tlsmap, "session-tickets", + &session_tickets_obj) == ISC_R_SUCCESS) + { + tls_session_tickets = + cfg_obj_asboolean(session_tickets_obj); + tls_session_tickets_set = true; + } } } @@ -11120,6 +11130,8 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, .ciphers = ciphers, .prefer_server_ciphers = tls_prefer_server_ciphers, .prefer_server_ciphers_set = tls_prefer_server_ciphers_set, + .session_tickets = tls_session_tickets, + .session_tickets_set = tls_session_tickets_set }; httpobj = cfg_tuple_get(ltup, "http"); diff --git a/bin/tests/system/checkconf/good-doh-tlsopts.conf b/bin/tests/system/checkconf/good-doh-tlsopts.conf index f6cafa342f7..0de934bfe42 100644 --- a/bin/tests/system/checkconf/good-doh-tlsopts.conf +++ b/bin/tests/system/checkconf/good-doh-tlsopts.conf @@ -16,6 +16,7 @@ tls local-tls { dhparam-file "dhparam.pem"; ciphers "HIGH:!aNULL:!MD5:!RC4"; prefer-server-ciphers yes; + session-tickets no; }; http local-http-server { diff --git a/bin/tests/system/checkconf/good-dot-tlsopts.conf b/bin/tests/system/checkconf/good-dot-tlsopts.conf index 8912646f65a..e68e6211e38 100644 --- a/bin/tests/system/checkconf/good-dot-tlsopts.conf +++ b/bin/tests/system/checkconf/good-dot-tlsopts.conf @@ -16,6 +16,7 @@ tls local-tls { dhparam-file "dhparam.pem"; ciphers "HIGH:!aNULL:!MD5:!RC4"; prefer-server-ciphers yes; + session-tickets no; }; options { diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index b6a7c14e273..bed3ed0140b 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -293,7 +293,7 @@ The following statements are supported: Declares communication channels to get access to ``named`` statistics. ``tls`` - Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``dhparam-file``, ``hostname``, ``ciphers``, ``protocols``, and ``prefer-server-ciphers``. + Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``dhparam-file``, ``hostname``, ``ciphers``, ``protocols``, ``prefer-server-ciphers``, and ``session-tickets``. ``http`` Specifies configuration information for an HTTP connection, including ``endponts``, ``listener-clients`` and ``streams-per-connection``. @@ -4795,6 +4795,13 @@ The following options can be specified in a ``tls`` statement: ``prefer-server-ciphers`` Specifies that server ciphers should be preferred over client ones. + ``session-tickets`` + Enables or disables session resumption through TLS session tickets, + as defined in RFC5077. Disabling the stateless session tickets + might be required in the cases when forward secrecy is needed, + or the TLS certificate and key pair is planned to be used across + multiple BIND instances. + There are two built-in TLS connection configurations: ``ephemeral``, uses a temporary key and certificate created for the current ``named`` session only, and ``none``, which can be used when setting up an HTTP diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index 036d5899495..30d73bab2f8 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -660,6 +660,7 @@ tls string { key\-file quoted_string; prefer\-server\-ciphers boolean; protocols { string; ... }; + session\-tickets boolean; }; .ft P .fi diff --git a/doc/misc/options b/doc/misc/options index da7fcceb311..06fec355aff 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -465,6 +465,7 @@ tls { key-file ; prefer-server-ciphers ; protocols { ; ... }; + session-tickets ; }; // may occur multiple times trust-anchors { ( static-key | diff --git a/doc/misc/options.active b/doc/misc/options.active index f579cc2835e..226e77da17f 100644 --- a/doc/misc/options.active +++ b/doc/misc/options.active @@ -462,6 +462,7 @@ tls { key-file ; prefer-server-ciphers ; protocols { ; ... }; + session-tickets ; }; // may occur multiple times trust-anchors { ( static-key | diff --git a/doc/misc/tls.grammar.rst b/doc/misc/tls.grammar.rst index 4cb078da947..98f724a6d8f 100644 --- a/doc/misc/tls.grammar.rst +++ b/doc/misc/tls.grammar.rst @@ -9,4 +9,5 @@ key-file ; prefer-server-ciphers ; protocols { ; ... }; + session-tickets ; }; diff --git a/lib/isc/include/isc/tls.h b/lib/isc/include/isc/tls.h index 5c32053df32..addc27ba5ca 100644 --- a/lib/isc/include/isc/tls.h +++ b/lib/isc/include/isc/tls.h @@ -124,6 +124,16 @@ isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer); * \li 'ctx' != NULL. */ +void +isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use); +/*%< + * Enable/Disable stateless session resumptions tickets on the given + * TLS context 'ctx' (see RFC5077). + * + * Requires: + * \li 'ctx' != NULL. + */ + isc_tls_t * isc_tls_create(isc_tlsctx_t *ctx); /*%< diff --git a/lib/isc/tls.c b/lib/isc/tls.c index f2dcbf187bc..94d42b7e174 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -574,6 +574,17 @@ isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer) { } } +void +isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use) { + REQUIRE(ctx != NULL); + + if (!use) { + (void)SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); + } else { + (void)SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET); + } +} + isc_tls_t * isc_tls_create(isc_tlsctx_t *ctx) { isc_tls_t *newctx = NULL; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 0f8329f26ad..7bff17d184b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -3891,6 +3891,7 @@ static cfg_clausedef_t tls_clauses[] = { { "protocols", &cfg_type_tlsprotos, 0 }, { "ciphers", &cfg_type_astring, 0 }, { "prefer-server-ciphers", &cfg_type_boolean, 0 }, + { "session-tickets", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; diff --git a/lib/ns/include/ns/listenlist.h b/lib/ns/include/ns/listenlist.h index 207c1f6ab38..8119821b5b8 100644 --- a/lib/ns/include/ns/listenlist.h +++ b/lib/ns/include/ns/listenlist.h @@ -67,6 +67,8 @@ typedef struct ns_listen_tls_params { const char *ciphers; bool prefer_server_ciphers; bool prefer_server_ciphers_set; + bool session_tickets; + bool session_tickets_set; } ns_listen_tls_params_t; /*** diff --git a/lib/ns/listenlist.c b/lib/ns/listenlist.c index 600ee64ceb7..6aa67dbd2bc 100644 --- a/lib/ns/listenlist.c +++ b/lib/ns/listenlist.c @@ -64,6 +64,11 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, isc_tlsctx_prefer_server_ciphers( sslctx, tls_params->prefer_server_ciphers); } + + if (tls_params->session_tickets_set) { + isc_tlsctx_session_tickets(sslctx, + tls_params->session_tickets); + } } elt = isc_mem_get(mctx, sizeof(*elt));