]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: implement keylog fetches for backend connections
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 19 Apr 2024 12:29:05 +0000 (14:29 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 19 Apr 2024 12:48:44 +0000 (14:48 +0200)
This patch implements the backend side of the keylog fetches.
The code was ready but needed the SSL message callbacks.

This could be used like this:

 log-format "CLIENT_EARLY_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_early_traffic_secret]\n
             CLIENT_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_handshake_traffic_secret]\n
             SERVER_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_server_handshake_traffic_secret]\n
             CLIENT_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_client_traffic_secret_0]\n
             SERVER_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_server_traffic_secret_0]\n
             EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_exporter_secret]\n
             EARLY_EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_early_exporter_secret]"

doc/configuration.txt
src/ssl_sample.c
src/ssl_sock.c

index 37bac688c1220795d42bd6d607aeaa54d621ba08..3612f05cac3651435bc1b0dec98c04a52955b917 100644 (file)
@@ -3923,13 +3923,16 @@ tune.ssl.keylog { on | off }
 
   SSLKEYLOGFILE Label             |  Sample fetches for the Secrets
   --------------------------------|-----------------------------------------
-  CLIENT_EARLY_TRAFFIC_SECRET     |  %[ssl_fc_client_early_traffic_secret]
-  CLIENT_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_fc_client_handshake_traffic_secret]
-  SERVER_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_fc_server_handshake_traffic_secret]
-  CLIENT_TRAFFIC_SECRET_0         |  %[ssl_fc_client_traffic_secret_0]
-  SERVER_TRAFFIC_SECRET_0         |  %[ssl_fc_server_traffic_secret_0]
-  EXPORTER_SECRET                 |  %[ssl_fc_exporter_secret]
-  EARLY_EXPORTER_SECRET           |  %[ssl_fc_early_exporter_secret]
+  CLIENT_EARLY_TRAFFIC_SECRET     |  %[ssl_xx_client_early_traffic_secret]
+  CLIENT_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_xx_client_handshake_traffic_secret]
+  SERVER_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_xx_server_handshake_traffic_secret]
+  CLIENT_TRAFFIC_SECRET_0         |  %[ssl_xx_client_traffic_secret_0]
+  SERVER_TRAFFIC_SECRET_0         |  %[ssl_xx_server_traffic_secret_0]
+  EXPORTER_SECRET                 |  %[ssl_xx_exporter_secret]
+  EARLY_EXPORTER_SECRET           |  %[ssl_xx_early_exporter_secret]
+
+  These fetches exists for frontend (fc) or backend (bc) sides, replace "xx" by
+  "fc" or "bc" to use the right side.
 
   This is only available with OpenSSL 1.1.1, and useful with TLS1.3 session.
 
@@ -3938,6 +3941,17 @@ tune.ssl.keylog { on | off }
 
   "CLIENT_RANDOM %[ssl_fc_client_random,hex] %[ssl_fc_session_key,hex]"
 
+  A complete keylog could be generate with a log-format these way, even though
+  this is not ideal for syslog:
+
+    log-format "CLIENT_EARLY_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_early_traffic_secret]\n
+                CLIENT_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_handshake_traffic_secret]\n
+                SERVER_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_server_handshake_traffic_secret]\n
+                CLIENT_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_client_traffic_secret_0]\n
+                SERVER_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_server_traffic_secret_0]\n
+                EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_exporter_secret]\n
+                EARLY_EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_early_exporter_secret]"
+
 tune.ssl.lifetime <timeout>
   Sets how long a cached SSL session may remain valid. This time is expressed
   in seconds and defaults to 300 (5 min). It is important to understand that it
@@ -22660,6 +22674,11 @@ ssl_bc_alg_keysize                                 integer
 ssl_bc_alpn                                        string
 ssl_bc_cipher                                      string
 ssl_bc_client_random                               binary
+ssl_bc_client_early_traffic_secret                 string
+ssl_bc_client_handshake_traffic_secret             string
+ssl_bc_client_traffic_secret_0                     string
+ssl_bc_exporter_secret                             string
+ssl_bc_early_exporter_secret                       string
 ssl_bc_curve                                       string
 ssl_bc_err                                         integer
 ssl_bc_err_str                                     string
@@ -22667,6 +22686,8 @@ ssl_bc_is_resumed                                  boolean
 ssl_bc_npn                                         string
 ssl_bc_protocol                                    string
 ssl_bc_unique_id                                   binary
+ssl_bc_server_handshake_traffic_secret             string
+ssl_bc_server_traffic_secret_0                     string
 ssl_bc_server_random                               binary
 ssl_bc_session_id                                  binary
 ssl_bc_session_key                                 binary
@@ -22800,6 +22821,51 @@ ssl_bc_client_random : binary
   sent using ephemeral ciphers. This requires OpenSSL >= 1.1.0, or BoringSSL.
   It can be used in a tcp-check or an http-check ruleset.
 
+ssl_bc_client_early_traffic_secret : string
+  Return the CLIENT_EARLY_TRAFFIC_SECRET as an hexadecimal string for the
+  back connection when the outgoing connection was made over a TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
+ssl_bc_client_handshake_traffic_secret : string
+  Return the CLIENT_HANDSHAKE_TRAFFIC_SECRET as an hexadecimal string for the
+  bacl connection when the outgoing connection was made over a TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
+ssl_bc_client_traffic_secret_0 : string
+  Return the CLIENT_TRAFFIC_SECRET_0 as an hexadecimal string for the
+  back connection when the outgoing connection was made over a TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
+ssl_bc_exporter_secret : string
+  Return the EXPORTER_SECRET as an hexadecimal string for the
+  back connection when the outgoing connection was made over a TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
+ssl_bc_early_exporter_secret : string
+  Return the EARLY_EXPORTER_SECRET as an hexadecimal string for the
+  back connection when the outgoing connection was made over an TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
 ssl_bc_curve : string
   Returns the name of the curve used in the key agreement when the outgoing
   connection was made over an SSL/TLS transport layer. This requires
@@ -22849,6 +22915,24 @@ ssl_bc_unique_id : binary
   can be encoded to base64 using the converter: "ssl_bc_unique_id,base64". It
   can be used in a tcp-check or an http-check ruleset.
 
+ssl_bc_server_handshake_traffic_secret : string
+  Return the SERVER_HANDSHAKE_TRAFFIC_SECRET as an hexadecimal string for the
+  back connection when the outgoing connection was made over a TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
+ssl_bc_server_traffic_secret_0 : string
+  Return the SERVER_TRAFFIC_SECRET_0 as an hexadecimal string for the
+  back connection when the outgoing connection was made over an TLS 1.3
+  transport layer.
+  Require OpenSSL >= 1.1.1. This is one of the keys dumped by the OpenSSL
+  keylog callback to generate the SSLKEYLOGFILE. The SSL Key logging must be
+  activated with "tune.ssl.keylog on" in the global section. See also
+  "tune.ssl.keylog"
+
 ssl_bc_server_random : binary
   Returns the server random of the back connection when the incoming connection
   was made over an SSL/TLS transport layer. It is useful to to decrypt traffic
index 5e7a278d7ce200a9530603fdde56174350b27c3f..0757c12d7ff4650fb1d400a4d2f4b0f44a8982c9 100644 (file)
@@ -2318,6 +2318,15 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
        { "ssl_bc_client_random",   smp_fetch_ssl_fc_random,      0,                   NULL,    SMP_T_BIN,  SMP_USE_L5SRV },
        { "ssl_bc_server_random",   smp_fetch_ssl_fc_random,      0,                   NULL,    SMP_T_BIN,  SMP_USE_L5SRV },
        { "ssl_bc_session_key",     smp_fetch_ssl_fc_session_key, 0,                   NULL,    SMP_T_BIN,  SMP_USE_L5SRV },
+#endif
+#ifdef HAVE_SSL_KEYLOG
+       { "ssl_bc_client_early_traffic_secret",     smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_client_handshake_traffic_secret", smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_server_handshake_traffic_secret", smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_client_traffic_secret_0",         smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_server_traffic_secret_0",         smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_exporter_secret",                 smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
+       { "ssl_bc_early_exporter_secret",           smp_fetch_ssl_x_keylog,       0,   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
 #endif
        { "ssl_bc_err",             smp_fetch_ssl_fc_err,         0,                   NULL,    SMP_T_SINT, SMP_USE_L5SRV },
        { "ssl_bc_err_str",         smp_fetch_ssl_fc_err_str,     0,                   NULL,    SMP_T_STR,  SMP_USE_L5SRV },
index e629ca2d8481364a4881f53b274f7ef60d80ddc4..9df175d93bbca4d130fd7fb08fa40f454b7283b7 100644 (file)
@@ -5147,6 +5147,13 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
 #ifdef SSL_CTRL_SET_MSG_CALLBACK
        SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
 #endif
+
+#ifdef HAVE_SSL_KEYLOG
+       /* only activate the keylog callback if it was required to prevent performance loss */
+       if (global_ssl.keylog > 0)
+               SSL_CTX_set_keylog_callback(ctx, SSL_CTX_keylog);
+#endif
+
 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
        if (srv->ssl_ctx.ciphersuites &&
                !SSL_CTX_set_ciphersuites(ctx, srv->ssl_ctx.ciphersuites)) {