From de29000e602bda55d32c266252ef63824e838ac0 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 24 Nov 2025 14:41:54 +0100 Subject: [PATCH] BUG/MEDIUM: server/ssl: Unset the SNI for new server connections if none is set When a new SSL server connection is created, if no SNI is set, it is possible to inherit from the one of the reused TLS session. The bug was introduced by the commit 95ac5fe4a ("MEDIUM: ssl_sock: always use the SSL's server name, not the one from the tid"). The mixup is possible between regular connections but also with health-checks connections. To fix the issue, when no SNI is set, for regular server connections and for health-check connections, the SNI must explicitly be disabled by calling ssl_sock_set_servername() with the hostname set to NULL. Many thanks to Lukas for his detailed bug report. This patch should fix the issue #3195. It must be backported as far as 3.0. --- src/backend.c | 22 +++++++++++++++------- src/tcpcheck.c | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/backend.c b/src/backend.c index 0170547b2..45dab68df 100644 --- a/src/backend.c +++ b/src/backend.c @@ -2156,14 +2156,22 @@ int connect_server(struct stream *s) #ifdef USE_OPENSSL /* Set socket SNI unless connection is reused. */ - if (conn_is_ssl(srv_conn) && srv && srv->ssl_ctx.sni && !(s->flags & SF_SRV_REUSED)) { - struct sample *sni_smp = NULL; + if (conn_is_ssl(srv_conn) && !(s->flags & SF_SRV_REUSED)) { + int sni_set = 0; - sni_smp = sample_fetch_as_type(s->be, s->sess, s, - SMP_OPT_DIR_REQ | SMP_OPT_FINAL, - srv->ssl_ctx.sni, SMP_T_STR); - if (smp_make_safe(sni_smp)) - ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area); + if (srv && srv->ssl_ctx.sni) { + struct sample *sni_smp = NULL; + + sni_smp = sample_fetch_as_type(s->be, s->sess, s, + SMP_OPT_DIR_REQ | SMP_OPT_FINAL, + srv->ssl_ctx.sni, SMP_T_STR); + if (smp_make_safe(sni_smp)) { + ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area); + sni_set = 1; + } + } + if (!sni_set) + ssl_sock_set_servername(srv_conn, NULL); } #endif /* USE_OPENSSL */ diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 815a84099..88a54d148 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -1509,6 +1509,8 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec ssl_sock_set_servername(conn, s->check.sni); else if (auto_sni) ssl_sock_set_servername(conn, b_orig(auto_sni)); + else + ssl_sock_set_servername(conn, NULL); if (connect->alpn) ssl_sock_set_alpn(conn, (unsigned char *)connect->alpn, connect->alpn_len);