]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: server: Don't rely on last default-server to init server SSL context
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 1 Dec 2021 08:50:41 +0000 (09:50 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 1 Dec 2021 10:47:08 +0000 (11:47 +0100)
During post-parsing stage, the SSL context of a server is initialized if SSL
is configured on the server or its default-server. It is required to be able
to enable SSL at runtime. However a regression was introduced, because the
last parsed default-server is used. But it is not necessarily the
default-server line used to configure the server. This may lead to
erroneously initialize the SSL context for a server without SSL parameter or
the skip it while it should be done.

The problem is the default-server used to configure a server is not saved
during configuration parsing. So, the information is lost during the
post-parsing. To fix the bug, the SRV_F_DEFSRV_USE_SSL flag is
introduced. It is used to know when a server was initialized with a
default-server using SSL.

For the record, the commit f63704488e ("MEDIUM: cli/ssl: configure ssl on
server at runtime") has introduced the bug.

This patch must be backported as far as 2.4.

include/haproxy/server-t.h
reg-tests/server/cli_set_ssl.vtc
src/cfgparse.c
src/server.c

index b17f0de46fdaf5ce7199da073249cbb906a0c479..71b8e4a873e5ecfd6be6c9f3d36aa5513a5bb3f6 100644 (file)
@@ -148,6 +148,7 @@ enum srv_initaddr {
 #define SRV_F_NO_RESOLUTION 0x0800       /* disable runtime DNS resolution on this server */
 #define SRV_F_DYNAMIC      0x1000        /* dynamic server instantiated at runtime */
 #define SRV_F_NON_PURGEABLE 0x2000       /* this server cannot be removed at runtime */
+#define SRV_F_DEFSRV_USE_SSL 0x4000      /* default-server uses SSL */
 
 /* configured server options for send-proxy (server->pp_opts) */
 #define SRV_PP_V1               0x0001   /* proxy protocol version 1 */
index 093943b00b2da17cbd46a89e8829158a36a16e9f..fa6fe68c5d89e42a127db5a16af55376bd6b8759 100644 (file)
@@ -26,8 +26,9 @@ haproxy h1 -conf {
         default_backend test0
 
     backend test0
-        default-server ssl
         server www0 ${s1_addr}:${s1_port} no-ssl
+        default-server ssl
+        server www1 ${s1_addr}:${s1_port} no-ssl
 
     backend test1
         server www0 ${s1_addr}:${s1_port} no-ssl
@@ -36,17 +37,22 @@ haproxy h1 -conf {
 haproxy h1 -cli {
     # supported case
     send "show servers state test0"
-    expect ~ "test0 1 www0 ${s1_addr} .* - ${s1_port} - -1"
-    send "set server test0/www0 ssl on"
+    expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - -1"
+    send "set server test0/www1 ssl on"
     expect ~ "server ssl setting updated"
     send "show servers state test0"
-    expect ~ "test0 1 www0 ${s1_addr} .* - ${s1_port} - 1"
-    send "set server test0/www0 ssl off"
+    expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - 1"
+    send "set server test0/www1 ssl off"
     expect ~ "server ssl setting updated"
     send "show servers state test0"
-    expect ~ "test0 1 www0 ${s1_addr} .* - ${s1_port} - 0"
+    expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - 0"
+
+    # unsupported cases
+    send "show servers state test0"
+    expect ~ "test0 1 www0 ${s1_addr} .* - ${s1_port} - -1"
+    send "set server test0/www0 ssl on"
+    expect ~ "'set server <srv> ssl' cannot be set"
 
-    # unsupported case
     send "show servers state test1"
     expect ~ "test1 1 www0 ${s1_addr} .* - ${s1_port} - -1"
     send "set server test1/www0 ssl on"
index 58067c8edfe35e66c9a6ee6d563ab1f64bc58564..06352e294f239e1b869f600e3af405d5399abb7f 100644 (file)
@@ -3399,8 +3399,8 @@ out_uri_auth_compat:
                         * if default-server have use_ssl, prerare ssl init
                         * without activating it */
                        if (newsrv->use_ssl == 1 || newsrv->check.use_ssl == 1 ||
-                               (newsrv->proxy->options & PR_O_TCPCHK_SSL) ||
-                               (newsrv->use_ssl != 1 && curproxy->defsrv.use_ssl == 1)) {
+                           (newsrv->proxy->options & PR_O_TCPCHK_SSL) ||
+                           ((newsrv->flags & SRV_F_DEFSRV_USE_SSL) && newsrv->use_ssl != 1)) {
                                if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
                                        cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
                        }
index a8e85a982ef5df3b69ec09b434e95ea38bc3b843..47bd38bc0657efe8ebeb30c0aa52c7da413f062a 100644 (file)
@@ -2049,6 +2049,10 @@ static void srv_conn_src_cpy(struct server *srv, struct server *src)
 #if defined(USE_OPENSSL)
 static void srv_ssl_settings_cpy(struct server *srv, struct server *src)
 {
+       /* <src> is the current proxy's default server and SSL is enabled */
+       if (src == &srv->proxy->defsrv && src->use_ssl == 1)
+               srv->flags |= SRV_F_DEFSRV_USE_SSL;
+
        if (src->ssl_ctx.ca_file != NULL)
                srv->ssl_ctx.ca_file = strdup(src->ssl_ctx.ca_file);
        if (src->ssl_ctx.crl_file != NULL)