in the context of a progressive migration, we want to be able to
activate SSL ciphering on outgoing connections to the server at runtime
without reloading.
This patch adds a `set server ssl` command to allow that:

- call common `srv_init_sslctx` from previous commit rework
- call `prepare_srv` to init ctx when enabling ssl
- call `destroy_srv` to deinit ctx when disabling ssl
- update doc

Signed-off-by: William Dauchy <[email protected]>
---
 doc/management.txt       |  3 +++
 include/haproxy/server.h |  1 +
 src/server.c             | 33 ++++++++++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/doc/management.txt b/doc/management.txt
index 66c973278..c616a0abb 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1846,6 +1846,9 @@ set server <backend>/<server> fqdn <FQDN>
   Change a server's FQDN to the value passed in argument. This requires the
   internal run-time DNS resolver to be configured and enabled for this server.
 
+set server <backend>/<server> ssl [ on | off ]
+  This option configures SSL ciphering on outgoing connections to the server.
+
 set severity-output [ none | number | string ]
   Change the severity output format of the stats socket connected to for the
   duration of the current session.
diff --git a/include/haproxy/server.h b/include/haproxy/server.h
index 64951374b..09938fcc1 100644
--- a/include/haproxy/server.h
+++ b/include/haproxy/server.h
@@ -56,6 +56,7 @@ int srv_init_addr(void);
 struct server *cli_find_server(struct appctx *appctx, char *arg);
 struct server *new_server(struct proxy *proxy);
 void srv_init_sslctx(struct server *s);
+void srv_set_ssl(struct server *s, signed char use_ssl);
 
 /* functions related to server name resolution */
 int snr_update_srv_status(struct server *s, int has_no_ip);
diff --git a/src/server.c b/src/server.c
index 74f829674..92bc128fc 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1226,6 +1226,28 @@ void srv_init_sslctx(struct server *s)
                s->ssl_ctx.methods.max = 
global_ssl.connect_default_sslmethods.max;
 }
 
+/* Configure ssl on server <s>.
+ * do nothing if there is no change to apply
+ *
+ * Must be called with the server lock held.
+ */
+void srv_set_ssl(struct server *s, signed char use_ssl)
+{
+       if (s->use_ssl == use_ssl)
+               return;
+
+       s->use_ssl = use_ssl;
+       if (s->use_ssl == 1) {
+               srv_init_sslctx(s);
+
+               if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
+                       xprt_get(XPRT_SSL)->prepare_srv(s);
+       } else {
+               if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
+                       xprt_get(XPRT_SSL)->destroy_srv(s);
+               s->xprt = xprt_get(XPRT_RAW);
+       }
+}
 
 /* Note: must not be declared <const> as its list will be overwritten.
  * Please take care of keeping this list alphabetically sorted, doing so helps
@@ -4402,10 +4424,19 @@ static int cli_parse_set_server(char **args, char 
*payload, struct appctx *appct
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
+       else if (strcmp(args[3], "ssl") == 0) {
+               if (strcmp(args[4], "on") == 0)
+                       srv_set_ssl(sv, 1);
+               else if (strcmp(args[4], "off") == 0)
+                       srv_set_ssl(sv, 0);
+               else
+                       cli_err(appctx, "'set server <srv> ssl' expects 'on' or 
'off'.\n");
+               cli_msg(appctx, LOG_NOTICE, "server ssl setting updated.\n");
+       }
        else {
                cli_err(appctx,
                        "'set server <srv>' only supports 'agent', 'health', 
'state',"
-                       " 'weight', 'addr', 'fqdn' and 'check-port'.\n");
+                       " 'weight', 'addr', 'fqdn', 'check-port' and 'ssl'.\n");
        }
  out_unlock:
        HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
-- 
2.28.0


Reply via email to