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/ssl_sock.h |  1 +
 src/server.c               | 16 +++++++++++++++-
 src/ssl_sock.c             | 23 +++++++++++++++++++++++
 4 files changed, 42 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/ssl_sock.h b/include/haproxy/ssl_sock.h
index 987a8fb32..6114c4e62 100644
--- a/include/haproxy/ssl_sock.h
+++ b/include/haproxy/ssl_sock.h
@@ -66,6 +66,7 @@ int ssl_sock_parse_alpn(char *arg, char **alpn_str, int 
*alpn_len, char **err);
 void ssl_sock_set_alpn(struct connection *conn, const unsigned char *, int);
 void ssl_sock_set_servername(struct connection *conn, const char *hostname);
 void ssl_sock_init_srv(struct server *s);
+void ssl_sock_set_srv(struct server *s, signed char use_ssl);
 
 int ssl_sock_get_cert_used_sess(struct connection *conn);
 int ssl_sock_get_cert_used_conn(struct connection *conn);
diff --git a/src/server.c b/src/server.c
index b1656d5ce..7db8507a1 100644
--- a/src/server.c
+++ b/src/server.c
@@ -38,6 +38,7 @@
 #include <haproxy/queue.h>
 #include <haproxy/sample.h>
 #include <haproxy/server.h>
+#include <haproxy/ssl_sock.h>
 #include <haproxy/stats-t.h>
 #include <haproxy/stream.h>
 #include <haproxy/stream_interface.h>
@@ -4380,10 +4381,23 @@ 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) {
+#ifdef USE_OPENSSL
+               if (strcmp(args[4], "on") == 0)
+                       ssl_sock_set_srv(sv, 1);
+               else if (strcmp(args[4], "off") == 0)
+                       ssl_sock_set_srv(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_msg(appctx, LOG_NOTICE, "server ssl setting not 
supported.\n");
+#endif
+       }
        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);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 0ef7a912b..fca6f3cec 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6819,6 +6819,29 @@ static void __ssl_sock_deinit(void)
        BIO_meth_free(ha_meth);
 }
 
+/* Configure ssl on server <s>.
+ * do nothing if there is no change to apply
+ *
+ * Must be called with the server lock held.
+ */
+void ssl_sock_set_srv(struct server *s, signed char use_ssl)
+{
+       if (s->use_ssl == use_ssl)
+               return;
+
+       s->use_ssl = use_ssl;
+       if (s->use_ssl == 1) {
+               ssl_sock_init_srv(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);
+       }
+}
+
 /*
  * Local variables:
  *  c-indent-level: 8
-- 
2.28.0


Reply via email to