From: Yorgos Thessalonikefs Date: Mon, 29 Sep 2025 10:03:56 +0000 (+0200) Subject: Fix #1346: [FR] Please allow back TLS 1.2. (#1349) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=499a3a7a612ad1e5ef5678bdb1bb6c059599419a;p=thirdparty%2Funbound.git Fix #1346: [FR] Please allow back TLS 1.2. (#1349) * 'tls-use-system-policy-versions' is introduced to allow Unbound to use any system available TLS version when serving TLS. * Apply suggestions from code review --------- Co-authored-by: Wouter Wijngaards --- diff --git a/daemon/remote.c b/daemon/remote.c index e10dadde7..8408e2273 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -153,7 +153,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg) log_crypto_err("could not SSL_CTX_new"); return 0; } - if(!listen_sslctx_setup(rc->ctx)) { + if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) { return 0; } diff --git a/daemon/unbound.c b/daemon/unbound.c index 164d0fb89..688804743 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -473,7 +473,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg) cfg->tls_ciphers, cfg->tls_ciphersuites, (cfg->tls_session_ticket_keys.first && cfg->tls_session_ticket_keys.first->str[0] != 0), - is_dot, is_doh))) { + is_dot, is_doh, cfg->tls_use_system_policy_versions))) { fatal_exit("could not set up listen SSL_CTX"); } } diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index a01627de9..c0d344cbb 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip, s->ev_cb = ev_cb; s->data = data; s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem, - NULL, NULL, 0, 0, 0); + NULL, NULL, 0, 0, 0, 0); if(!s->sslctx) { log_err("could not create ssl context"); free(s->ip); diff --git a/doc/example.conf.in b/doc/example.conf.in index 02f6ec774..54adee889 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -932,21 +932,26 @@ server: # https-port: 443 # quic-port: 853 + # Also serve tls on these port numbers (eg. 443, ...), by listing + # tls-additional-port: portno for each of the port numbers. + # cipher setting for TLSv1.2 # tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256" # cipher setting for TLSv1.3 # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" - # Pad responses to padded queries received over TLS - # pad-responses: yes - - # Padded responses will be padded to the closest multiple of this size. - # pad-responses-block-size: 468 - # Use the SNI extension for TLS connections. Default is yes. # Changing the value requires a reload. # tls-use-sni: yes + # Allow general-purpose version-flexible TLS server configuration that + # may be further restricted by the system's policy. + # Use only if you want to support legacy TLS client connections. + # Default is no and Unbound will only use the latest available TLS + # version. + # Changing the value requires a reload. + # tls-use-system-policy-versions: no + # Add the secret file for TLS Session Ticket. # Secret file must be 80 bytes of random data. # First key use to encrypt and decrypt TLS session tickets. @@ -967,15 +972,18 @@ server: # and on other systems, the default openssl certificates # tls-system-cert: no + # Pad responses to padded queries received over TLS + # pad-responses: yes + + # Padded responses will be padded to the closest multiple of this size. + # pad-responses-block-size: 468 + # Pad queries over TLS upstreams # pad-queries: yes # Padded queries will be padded to the closest multiple of this size. # pad-queries-block-size: 128 - # Also serve tls on these port numbers (eg. 443, ...), by listing - # tls-additional-port: portno for each of the port numbers. - # HTTP endpoint to provide DNS-over-HTTPS service on. # http-endpoint: "/dns-query" diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 0d2b5044b..08a926bd5 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1218,6 +1218,47 @@ Default: \(dq\(dq .UNINDENT .INDENT 0.0 .TP +.B tls\-use\-sni: \fI\fP +Enable or disable sending the SNI extension on TLS connections. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Changing the value requires a reload. +.UNINDENT +.UNINDENT +.sp +Default: yes +.UNINDENT +.INDENT 0.0 +.TP +.B tls\-use\-system\-policy\-versions: \fI\fP +Enable or disable general\-puspose version\-flexible TLS server configuration +when serving TLS. +This will allow the whole list of available TLS versions provided by the +crypto library, which may have been further restricted by the system\(aqs +crypto policy. +.sp +By default Unbound only uses the latest available TLS version. +.sp +\fBCAUTION:\fP +.INDENT 7.0 +.INDENT 3.5 +Use only if you want to support legacy TLS client connections. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Changing the value requires a reload. +.UNINDENT +.UNINDENT +.sp +Default: no +.UNINDENT +.INDENT 0.0 +.TP .B pad\-responses: \fI\fP If enabled, TLS serviced queries that contained an EDNS Padding option will cause responses padded to the closest multiple of the size specified in @@ -1251,20 +1292,6 @@ Default: 128 .UNINDENT .INDENT 0.0 .TP -.B tls\-use\-sni: \fI\fP -Enable or disable sending the SNI extension on TLS connections. -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -Changing the value requires a reload. -.UNINDENT -.UNINDENT -.sp -Default: yes -.UNINDENT -.INDENT 0.0 -.TP .B https\-port: \fI\fP The port number on which to provide DNS\-over\-HTTPS service. Only interfaces configured with that port number as @number get the HTTPS diff --git a/doc/unbound.conf.rst b/doc/unbound.conf.rst index bbc31fe50..f9f2dea8a 100644 --- a/doc/unbound.conf.rst +++ b/doc/unbound.conf.rst @@ -1103,6 +1103,30 @@ These options are part of the **server:** clause. Default: "" +@@UAHL@unbound.conf@tls-use-sni@@: ** + Enable or disable sending the SNI extension on TLS connections. + + .. note:: Changing the value requires a reload. + + Default: yes + + +@@UAHL@unbound.conf@tls-use-system-policy-versions@@: ** + Enable or disable general-puspose version-flexible TLS server configuration + when serving TLS. + This will allow the whole list of available TLS versions provided by the + crypto library, which may have been further restricted by the system's + crypto policy. + + By default Unbound only uses the latest available TLS version. + + .. caution:: Use only if you want to support legacy TLS client connections. + + .. note:: Changing the value requires a reload. + + Default: no + + @@UAHL@unbound.conf@pad-responses@@: ** If enabled, TLS serviced queries that contained an EDNS Padding option will cause responses padded to the closest multiple of the size specified in @@ -1132,14 +1156,6 @@ These options are part of the **server:** clause. Default: 128 -@@UAHL@unbound.conf@tls-use-sni@@: ** - Enable or disable sending the SNI extension on TLS connections. - - .. note:: Changing the value requires a reload. - - Default: yes - - @@UAHL@unbound.conf@https-port@@: ** The port number on which to provide DNS-over-HTTPS service. Only interfaces configured with that port number as @number get the HTTPS diff --git a/util/config_file.c b/util/config_file.c index b1e767b3b..f611a96e4 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -129,6 +129,7 @@ config_create(void) cfg->tls_cert_bundle = NULL; cfg->tls_win_cert = 0; cfg->tls_use_sni = 1; + cfg->tls_use_system_policy_versions = 0; cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT; if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit; cfg->http_max_streams = 100; @@ -628,6 +629,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_STR("tls-ciphers:", tls_ciphers) else S_STR("tls-ciphersuites:", tls_ciphersuites) else S_YNO("tls-use-sni:", tls_use_sni) + else S_YNO("tls-use-system-policy-versions:", tls_use_system_policy_versions) else S_NUMBER_NONZERO("https-port:", https_port) else S_STR("http-endpoint:", http_endpoint) else S_NUMBER_NONZERO("http-max-streams:", http_max_streams) @@ -1179,6 +1181,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_STR(opt, "tls-ciphers", tls_ciphers) else O_STR(opt, "tls-ciphersuites", tls_ciphersuites) else O_YNO(opt, "tls-use-sni", tls_use_sni) + else O_YNO(opt, "tls-use-system-policy-versions", tls_use_system_policy_versions) else O_DEC(opt, "https-port", https_port) else O_STR(opt, "http-endpoint", http_endpoint) else O_UNS(opt, "http-max-streams", http_max_streams) diff --git a/util/config_file.h b/util/config_file.h index 44ac036b8..dd32f0d9f 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -148,6 +148,8 @@ struct config_file { char* tls_ciphersuites; /** if SNI is to be used */ int tls_use_sni; + /** if all TLS versions can be used; based on system policy (if any) */ + int tls_use_system_policy_versions; /** port on which to provide DNS over HTTPS service */ int https_port; diff --git a/util/configlexer.lex b/util/configlexer.lex index bc258673d..8e38ef468 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -262,6 +262,7 @@ tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) } tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) } tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) } tls-use-sni{COLON} { YDVAR(1, VAR_TLS_USE_SNI) } +tls-use-system-policy-versions{COLON} { YDVAR(1, VAR_TLS_USE_SYSTEM_POLICY_VERSIONS) } https-port{COLON} { YDVAR(1, VAR_HTTPS_PORT) } http-endpoint{COLON} { YDVAR(1, VAR_HTTP_ENDPOINT) } http-max-streams{COLON} { YDVAR(1, VAR_HTTP_MAX_STREAMS) } diff --git a/util/configparser.y b/util/configparser.y index 82e1d8782..ced904669 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -199,6 +199,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE %token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI +%token VAR_TLS_USE_SYSTEM_POLICY_VERSIONS %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE %token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME @@ -346,6 +347,7 @@ content_server: server_num_threads | server_verbosity | server_port | server_tls_ciphersuites | server_tls_session_ticket_keys | server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie | server_tls_use_sni | server_edns_client_string | + server_tls_use_system_policy_versions | server_edns_client_string_opcode | server_nsid | server_zonemd_permissive_mode | server_max_reuse_tcp_queries | server_tcp_reuse_timeout | server_tcp_auth_query_timeout | @@ -1154,6 +1156,15 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG free($2); } ; +server_tls_use_system_policy_versions: VAR_TLS_USE_SYSTEM_POLICY_VERSIONS STRING_ARG + { + OUTYY(("P(server_tls_use_system_policy_versions:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->tls_use_system_policy_versions = (strcmp($2, "yes")==0); + free($2); + } + ; server_https_port: VAR_HTTPS_PORT STRING_ARG { OUTYY(("P(server_https_port:%s)\n", $2)); diff --git a/util/net_help.c b/util/net_help.c index 6ce0d9131..426ace934 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1226,7 +1226,7 @@ setup_ticket_keys_cb(void* sslctx) #endif /* HAVE_SSL */ int -listen_sslctx_setup(void* ctxt) +listen_sslctx_setup(void* ctxt, int use_system_versions) { #ifdef HAVE_SSL SSL_CTX* ctx = (SSL_CTX*)ctxt; @@ -1238,35 +1238,37 @@ listen_sslctx_setup(void* ctxt) return 0; } #endif - if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) - != SSL_OP_NO_SSLv3){ - log_crypto_err("could not set SSL_OP_NO_SSLv3"); - return 0; - } + if(!use_system_versions) { + if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) + != SSL_OP_NO_SSLv3){ + log_crypto_err("could not set SSL_OP_NO_SSLv3"); + return 0; + } #if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1) - /* if we have tls 1.1 disable 1.0 */ - if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1) - != SSL_OP_NO_TLSv1){ - log_crypto_err("could not set SSL_OP_NO_TLSv1"); - return 0; - } + /* if we have tls 1.1 disable 1.0 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1) + != SSL_OP_NO_TLSv1){ + log_crypto_err("could not set SSL_OP_NO_TLSv1"); + return 0; + } #endif #if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2) - /* if we have tls 1.2 disable 1.1 */ - if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1) - != SSL_OP_NO_TLSv1_1){ - log_crypto_err("could not set SSL_OP_NO_TLSv1_1"); - return 0; - } + /* if we have tls 1.2 disable 1.1 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1) + != SSL_OP_NO_TLSv1_1){ + log_crypto_err("could not set SSL_OP_NO_TLSv1_1"); + return 0; + } #endif #if defined(SSL_OP_NO_TLSv1_2) && defined(SSL_OP_NO_TLSv1_3) - /* if we have tls 1.3 disable 1.2 */ - if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2) - != SSL_OP_NO_TLSv1_2){ - log_crypto_err("could not set SSL_OP_NO_TLSv1_2"); - return 0; - } + /* if we have tls 1.3 disable 1.2 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2) + != SSL_OP_NO_TLSv1_2){ + log_crypto_err("could not set SSL_OP_NO_TLSv1_2"); + return 0; + } #endif + } #if defined(SSL_OP_NO_RENEGOTIATION) /* disable client renegotiation */ if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & @@ -1341,7 +1343,7 @@ listen_sslctx_setup_2(void* ctxt) void* listen_sslctx_create(const char* key, const char* pem, const char* verifypem, const char* tls_ciphers, const char* tls_ciphersuites, int set_ticket_keys_cb, - int is_dot, int is_doh) + int is_dot, int is_doh, int use_system_versions) { #ifdef HAVE_SSL SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); @@ -1359,7 +1361,7 @@ void* listen_sslctx_create(const char* key, const char* pem, SSL_CTX_free(ctx); return NULL; } - if(!listen_sslctx_setup(ctx)) { + if(!listen_sslctx_setup(ctx, use_system_versions)) { SSL_CTX_free(ctx); return NULL; } diff --git a/util/net_help.h b/util/net_help.h index 278e370a2..7b8a20642 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -478,9 +478,11 @@ void log_cert(unsigned level, const char* str, void* cert); /** * Set SSL_OP_NOxxx options on SSL context to disable bad crypto * @param ctxt: SSL_CTX* + * @param use_system_versions: rely on the system policy (if any) for allowed + * TLS versions * @return false on failure. */ -int listen_sslctx_setup(void* ctxt); +int listen_sslctx_setup(void* ctxt, int use_system_versions); /** * Further setup of listening SSL context, after keys loaded. @@ -499,12 +501,14 @@ void listen_sslctx_setup_2(void* ctxt); * to be set. * @param is_dot: if the TLS connection is for DoT to set the appropriate ALPN. * @param is_doh: if the TLS connection is for DoH to set the appropriate ALPN. + * @param use_system_versions: rely on the system policy (if any) for allowed + * TLS versions * return SSL_CTX* or NULL on failure (logged). */ void* listen_sslctx_create(const char* key, const char* pem, const char* verifypem, const char* tls_ciphers, const char* tls_ciphersuites, int set_ticket_keys_cb, - int is_dot, int is_doh); + int is_dot, int is_doh, int use_system_versions); /** * create SSL connect context diff --git a/winrc/win_svc.c b/winrc/win_svc.c index 429b045dc..6fca0c7d5 100644 --- a/winrc/win_svc.c +++ b/winrc/win_svc.c @@ -369,7 +369,7 @@ service_init(int r, struct daemon** d, struct config_file** c) cfg->tls_ciphers, cfg->tls_ciphersuites, (cfg->tls_session_ticket_keys.first && cfg->tls_session_ticket_keys.first->str[0] != 0), - 1, 0))) { + 1, 0, cfg->tls_use_system_policy_versions))) { fatal_exit("could not set up listen SSL_CTX"); } #ifdef HAVE_NGHTTP2_NGHTTP2_H @@ -379,7 +379,7 @@ service_init(int r, struct daemon** d, struct config_file** c) cfg->tls_ciphers, cfg->tls_ciphersuites, (cfg->tls_session_ticket_keys.first && cfg->tls_session_ticket_keys.first->str[0] != 0), - 0, 1))) { + 0, 1, cfg->tls_use_system_policy_versions))) { fatal_exit("could not set up listen doh SSL_CTX"); } }