Le 11/29/21 à 09:56, Christian Ruppert a écrit :
Hey,

we have something like:
          server maint 192.168.70.98:80 weight 1 backup non-stick

          default-server check maxconn 100 ssl verify required sni
str(somestr) ca-file /etc/ssl/certs/ca-certificates.crt observe layer7

          server s200010 192.168.200.10:8443 cookie somecookie weight 100
check addr 127.0.0.1 port 62041 check inter 10000 fall 2 rise 2
          ...


In 2.2 (2.2.17) it is totally valid and the stats say the "maint" is
still "no check". In 2.4.9 the config verify fails. In 2.2 it seems to
only affects server's below default-server.
[ALERT]    (23456) : Proxy '...', server 'maint'
[/etc/haproxy/haproxy.cfg:104096] verify is enabled by default but no CA
file specified. If you're running on a LAN where you're certain to trust
the server's certificate, please set an explicit 'verify none' statement
on the 'server' line, or use 'ssl-server-verify none' in the global
section to disable server-side verifications by default.

We're using templates and share the maint server with several hundred
other listeners/backends. Only 5 are using a config like this here, with
SSL and verify.

Another problem here seems: "verify is enabled by default but no CA file
specified" while in fact it is?
Is this intended?


I pushed a patch (https://github.com/haproxy/haproxy/commit/4ab26796) that should fix this issue. It will be backported ASAP. In the mean time, the patch for the 2.4 is attached to this mail.

--
Christopher Faulet
From 7f689d5265a973d66b702e57ba02e866c1db400c Mon Sep 17 00:00:00 2001
From: Christopher Faulet <[email protected]>
Date: Wed, 1 Dec 2021 09:50:41 +0100
Subject: [PATCH] BUG/MINOR: server: Don't rely on last default-server to init
 server SSL context

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       |  3 +++
 reg-tests/server/cli_set_ssl.vtc | 20 +++++++++++++-------
 src/cfgparse.c                   |  4 ++--
 src/server.c                     |  4 ++++
 4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h
index 4291953888..402ea79f0a 100644
--- a/include/haproxy/server-t.h
+++ b/include/haproxy/server-t.h
@@ -149,6 +149,9 @@ enum srv_initaddr {
 #define SRV_F_SOCKS4_PROXY 0x0400        /* this server uses SOCKS4 proxy */
 #define SRV_F_NO_RESOLUTION 0x0800       /* disable runtime DNS resolution on this server */
 #define SRV_F_DYNAMIC      0x1000        /* dynamic server instantiated at runtime */
+/* 0x2000 unused */
+#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 */
diff --git a/reg-tests/server/cli_set_ssl.vtc b/reg-tests/server/cli_set_ssl.vtc
index 638debea0d..f97bf4de3a 100644
--- a/reg-tests/server/cli_set_ssl.vtc
+++ b/reg-tests/server/cli_set_ssl.vtc
@@ -27,8 +27,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
@@ -37,17 +38,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"
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 5423adab60..be0eaa7d12 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3540,8 +3540,8 @@ int check_config_validity()
 			 * 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);
 			}
diff --git a/src/server.c b/src/server.c
index 4ec9487955..50c5346ea7 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2062,6 +2062,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)
-- 
2.31.1

Reply via email to