From 1e6bba1612d9e3ea2ea7aba2d09dd29fda8b2958 Mon Sep 17 00:00:00 2001 From: koarz Date: Tue, 16 Dec 2025 11:44:10 +0800 Subject: [PATCH 1/2] feat: enable TLS key logging via SSLKEYLOGFILE env --- src/brpc/details/ssl_helper.cpp | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/brpc/details/ssl_helper.cpp b/src/brpc/details/ssl_helper.cpp index f38b16d6a5..4b5d2043a2 100644 --- a/src/brpc/details/ssl_helper.cpp +++ b/src/brpc/details/ssl_helper.cpp @@ -22,6 +22,9 @@ #ifndef USE_MESALINK #include // recv +#include // pthread_once +#include // fopen +#include // getenv #include #include #include @@ -185,6 +188,43 @@ static void SSLMessageCallback(int write_p, int version, int content_type, #endif // TLS1_RT_HEARTBEAT } +#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER >= 0x10101000L) +static pthread_once_t g_ssl_keylog_once = PTHREAD_ONCE_INIT; +static FILE* g_ssl_keylog_file = NULL; + +static void InitSSLKeyLogFile() { + const char* path = getenv("SSLKEYLOGFILE"); + if (path == NULL || path[0] == '\0') { + return; + } + g_ssl_keylog_file = fopen(path, "a"); + if (g_ssl_keylog_file == NULL) { + PLOG(WARNING) << "Fail to open SSLKEYLOGFILE=" << path; + } +} + +static void SSLKeyLogCallback(const SSL* ssl, const char* line) { + (void)ssl; + if (line == NULL) { + return; + } + // Write the full key log line with newline in one call to keep output atomic. + fprintf(g_ssl_keylog_file, "%s\n", line); + fflush(g_ssl_keylog_file); +} + +static void MaybeSetKeyLogCallback(SSL_CTX* ctx) { + pthread_once(&g_ssl_keylog_once, InitSSLKeyLogFile); + if (ctx != NULL && g_ssl_keylog_file != NULL) { + SSL_CTX_set_keylog_callback(ctx, SSLKeyLogCallback); + } +} +#else +static void MaybeSetKeyLogCallback(SSL_CTX* ctx) { + (void)ctx; +} +#endif + #ifndef OPENSSL_NO_DH static DH* SSLGetDHCallback(SSL* ssl, int exp, int keylen) { (void)exp; @@ -494,6 +534,7 @@ SSL_CTX* CreateClientSSLContext(const ChannelSSLOptions& options) { LOG(ERROR) << "Fail to new SSL_CTX: " << SSLError(ERR_get_error()); return NULL; } + MaybeSetKeyLogCallback(ssl_ctx.get()); if (!options.client_cert.certificate.empty() && LoadCertificate(ssl_ctx.get(), @@ -532,6 +573,7 @@ SSL_CTX* CreateServerSSLContext(const std::string& certificate, LOG(ERROR) << "Fail to new SSL_CTX: " << SSLError(ERR_get_error()); return NULL; } + MaybeSetKeyLogCallback(ssl_ctx.get()); if (LoadCertificate(ssl_ctx.get(), certificate, private_key, hostnames) != 0) { From 6ea77c7261c9e396f5b5657fbce4b0fc4a63910d Mon Sep 17 00:00:00 2001 From: koarz Date: Wed, 24 Dec 2025 18:44:50 +0800 Subject: [PATCH 2/2] fix --- src/brpc/details/ssl_helper.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/brpc/details/ssl_helper.cpp b/src/brpc/details/ssl_helper.cpp index 4b5d2043a2..322b9cc3ff 100644 --- a/src/brpc/details/ssl_helper.cpp +++ b/src/brpc/details/ssl_helper.cpp @@ -18,6 +18,7 @@ #include "brpc/ssl_options.h" +#include "butil/files/scoped_file.h" #include #ifndef USE_MESALINK @@ -197,20 +198,24 @@ static void InitSSLKeyLogFile() { if (path == NULL || path[0] == '\0') { return; } - g_ssl_keylog_file = fopen(path, "a"); + g_ssl_keylog_file = fopen(path, "ae"); if (g_ssl_keylog_file == NULL) { PLOG(WARNING) << "Fail to open SSLKEYLOGFILE=" << path; + } else { + setvbuf(g_ssl_keylog_file, NULL, _IOLBF, 0); + LOG(WARNING) << "SSLKEYLOGFILE is enabled (path: " << path << "). " + << "Sensitive TLS session keys will be written to this file. " + << "This feature is intended for debugging only and should NOT be used in production environments."; } } static void SSLKeyLogCallback(const SSL* ssl, const char* line) { (void)ssl; - if (line == NULL) { + if (line == NULL || g_ssl_keylog_file == NULL) { return; } // Write the full key log line with newline in one call to keep output atomic. fprintf(g_ssl_keylog_file, "%s\n", line); - fflush(g_ssl_keylog_file); } static void MaybeSetKeyLogCallback(SSL_CTX* ctx) {