MINOR: ssl/log: add keylog format variables and env vars

Add keylog_format_fc and keylog_format_bc global variables containing
the SSLKEYLOGFILE log-format strings for the frontend (client-facing)
and backend (server-facing) TLS connections respectively. These produce
output compatible with the SSLKEYLOGFILE format described at:
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html

Both formats are also exported as environment variables at startup:
  HAPROXY_KEYLOG_FC_LOG_FMT
  HAPROXY_KEYLOG_BC_LOG_FMT

These variables contains \n so they might not be compatible with syslog
servers, using them with stderr or a sink might be required.

These can be referenced directly in "log-format" directives to produce
SSLKEYLOGFILE-compatible output, usable by network analyzers such as
Wireshark to decrypt captured TLS traffic.
This commit is contained in:
William Lallemand 2026-04-01 10:56:24 +02:00
parent e264523112
commit c8bfd06b57
5 changed files with 129 additions and 18 deletions

View File

@ -990,23 +990,26 @@ within conditional blocks and not to reference them in the global section's
The table below summaries the status of each variable for the different working
modes:
+--------------------------+---------+------------+-----------+
| variable | usable | modifiable | listed |
| +---------+------------+-----------+
| | M | W | M | W | M | W |
+--------------------------+----+----+------+-----+-----+-----+
| HAPROXY_STARTUP_VERSION | X | X | | | X | X |
| HAPROXY_BRANCH | X | X | | | X | X |
| HAPROXY_CFGFILES | | | | | X | X |
| HAPROXY_MWORKER | | | | | X | X |
| HAPROXY_CLI | | | | | | X |
| HAPROXY_MASTER_CLI | | | | | X | |
| HAPROXY_LOCALPEER | | X | | | | X |
| HAPROXY_HTTP_LOG_FMT | | X | | X | | |
| HAPROXY_HTTP_CLF_LOG_FMT | | X | | X | | |
| HAPROXY_HTTPS_LOG_FMT | | X | | X | | |
| HAPROXY_TCP_LOG_FMT | | X | | X | | |
+--------------------------+----+----+------+-----+-----+-----+
+---------------------------+---------+------------+-----------+
| variable | usable | modifiable | listed |
| +---------+------------+-----------+
| | M | W | M | W | M | W |
+---------------------------+----+----+------+-----+-----+-----+
| HAPROXY_STARTUP_VERSION | X | X | | | X | X |
| HAPROXY_BRANCH | X | X | | | X | X |
| HAPROXY_CFGFILES | | | | | X | X |
| HAPROXY_MWORKER | | | | | X | X |
| HAPROXY_CLI | | | | | | X |
| HAPROXY_MASTER_CLI | | | | | X | |
| HAPROXY_LOCALPEER | | X | | | | X |
| HAPROXY_HTTP_LOG_FMT | | X | | X | | |
| HAPROXY_HTTP_CLF_LOG_FMT | | X | | X | | |
| HAPROXY_HTTPS_LOG_FMT | | X | | X | | |
| HAPROXY_TCP_LOG_FMT | | X | | X | | |
| HAPROXY_TCP_CLF_LOG_FMT | | X | | X | | |
| HAPROXY_KEYLOG_FC_LOG_FMT | | X | | X | | |
| HAPROXY_KEYLOG_BC_LOG_FMT | | X | | X | | |
+---------------------------+----+----+------+-----+-----+-----+
The variables in question are the following:
@ -1039,6 +1042,16 @@ The variables in question are the following:
* HAPROXY_TCP_CLF_LOG_FMT: similar to HAPROXY_HTTP_CLF_LOG_FMT but for TCP
CLF log format as defined in section 8.2.2 "TCP log format".
* HAPROXY_KEYLOG_FC_LOG_FMT: contains the keylog format for the frontend
(client-facing) TLS connection, with key entries separated by newlines so
it might not be compatible with your syslog server. "tune.ssl.keylog on" is
required.
* HAPROXY_KEYLOG_BC_LOG_FMT: similar to HAPROXY_KEYLOG_FC_LOG_FMT but for the
backend (server-facing) TLS connection. Key entries are separated by
newlines so it might not be compatible with your syslog server.
"tune.ssl.keylog on" is required.
* HAPROXY_MWORKER: In master-worker mode, this variable is set to 1.
* HAPROXY_CLI: configured listeners addresses of the stats socket of every
@ -5531,6 +5544,12 @@ tune.ssl.keylog { on | off }
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]"
HAProxy also provides the above formats as predefined environment variables
that can be used directly in a "log-format" directive:
$HAPROXY_KEYLOG_FC_LOG_FMT frontend (client-facing) connection keys
$HAPROXY_KEYLOG_BC_LOG_FMT backend (server-facing) connection keys
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

69
examples/keylog-test.cfg Normal file
View File

@ -0,0 +1,69 @@
# Example: log HTTP traffic and TLS session keys to separate destinations
#
# "option httpslog" sends HTTP access logs to the /dev/log syslog server.
# TLS session keys are written to 2 ring buffers.
#
# Requirements:
# - HAProxy built with OpenSSL support
# - "tune.ssl.keylog on" in the global section
#
# Retrieve TLS session keys from the ring buffer via the CLI:
# For frontend connections:
#
# (echo "show events keylog-fc -w"; read) | socat /tmp/worker.socket -
#
# For backend connections:
#
# (echo "show events keylog-bc -w"; read) | socat /tmp/worker.socket -
#
# The result is in SSLKEYLOGFILE format and can be saved to a file and loaded
# into Wireshark to decrypt captured TLS traffic.
global
stats socket /tmp/worker.socket mode 0660
tune.ssl.keylog on
# Ring buffer for TLS session keys.
# "format raw" stores only the log message text, without any syslog envelope,
# producing output in the SSLKEYLOGFILE format directly.
ring keylog-fc
description "TLS session key frontend log"
format raw
maxlen 2000
size 1M
ring keylog-bc
description "TLS session key backend log"
format raw
maxlen 2000
size 1M
defaults
mode http
timeout client 30s
timeout server 30s
timeout connect 5s
log-profile keylog-fc
on any format "${HAPROXY_KEYLOG_FC_LOG_FMT}"
log-profile keylog-bc
on any format "${HAPROXY_KEYLOG_BC_LOG_FMT}"
frontend https-in
bind :443 ssl crt "common.pem"
option httpslog
# HTTPs access logs sent to the syslog server
log /dev/log format raw local0
# TLS session keys written to the ring buffer
log ring@keylog-fc profile keylog-fc local1
log ring@keylog-bc profile keylog-bc local1
default_backend be1
backend be1
server s1 10.0.0.123:443 ssl verify none

View File

@ -42,6 +42,8 @@ extern char clf_tcp_log_format[];
extern char default_http_log_format[];
extern char clf_http_log_format[];
extern char default_https_log_format[];
extern char keylog_format_fc[];
extern char keylog_format_bc[];
extern char default_rfc5424_sd_log_format[];

View File

@ -1121,6 +1121,8 @@ static int read_cfg()
setenv("HAPROXY_HTTPS_LOG_FMT", default_https_log_format, 1);
setenv("HAPROXY_TCP_LOG_FMT", default_tcp_log_format, 1);
setenv("HAPROXY_TCP_CLF_LOG_FMT", clf_tcp_log_format, 1);
setenv("HAPROXY_KEYLOG_FC_LOG_FMT", keylog_format_fc, 1);
setenv("HAPROXY_KEYLOG_BC_LOG_FMT", keylog_format_bc, 1);
setenv("HAPROXY_BRANCH", PRODUCT_BRANCH, 1);
list_for_each_entry(cfg, &cfg_cfgfiles, list) {
int ret;

View File

@ -334,6 +334,23 @@ char default_tcp_log_format[] = "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%
char clf_tcp_log_format[] = "%{+Q}o %{-Q}ci - - [%T] \"TCP \" 000 %B \"\" \"\" %cp %ms %ft %b %s %Th %Tw %Tc %Tt %U %ts-- %ac %fc %bc %sc %rc %sq %bq \"\" \"\" ";
char *log_format = NULL;
char keylog_format_bc[] = "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]";
char keylog_format_fc[] = "CLIENT_EARLY_TRAFFIC_SECRET %[ssl_fc_client_random,hex] %[ssl_fc_client_early_traffic_secret]\n"
"CLIENT_HANDSHAKE_TRAFFIC_SECRET %[ssl_fc_client_random,hex] %[ssl_fc_client_handshake_traffic_secret]\n"
"SERVER_HANDSHAKE_TRAFFIC_SECRET %[ssl_fc_client_random,hex] %[ssl_fc_server_handshake_traffic_secret]\n"
"CLIENT_TRAFFIC_SECRET_0 %[ssl_fc_client_random,hex] %[ssl_fc_client_traffic_secret_0]\n"
"SERVER_TRAFFIC_SECRET_0 %[ssl_fc_client_random,hex] %[ssl_fc_server_traffic_secret_0]\n"
"EXPORTER_SECRET %[ssl_fc_client_random,hex] %[ssl_fc_exporter_secret]\n"
"EARLY_EXPORTER_SECRET %[ssl_fc_client_random,hex] %[ssl_fc_early_exporter_secret]";
/* Default string used for structured-data part in RFC5424 formatted
* syslog messages.
*/
@ -351,7 +368,9 @@ static inline int logformat_str_isdefault(const char *str)
str == clf_http_log_format ||
str == default_tcp_log_format ||
str == clf_tcp_log_format ||
str == default_rfc5424_sd_log_format;
str == default_rfc5424_sd_log_format ||
str == keylog_format_bc ||
str == keylog_format_fc;
}
/* free logformat str if it is not a default (static) one */