From 72c654928af68a9f22a43bb6e343ff1f95ea5180 Mon Sep 17 00:00:00 2001 From: Karel Bilek Date: Mon, 9 Dec 2024 09:44:51 +0100 Subject: [PATCH] Allow setting keyLogFile to DoT/DoH backends --- pdns/dnsdistdist/dnsdist-lua.cc | 9 +++++++++ pdns/dnsdistdist/docs/reference/config.rst | 1 + pdns/dnsdistdist/doh.cc | 2 +- pdns/libssl.cc | 6 +++--- pdns/libssl.hh | 2 +- pdns/tcpiohandler.cc | 7 ++++++- pdns/tcpiohandler.hh | 1 + 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-lua.cc b/pdns/dnsdistdist/dnsdist-lua.cc index fa0940a988a2..646b1f23942a 100644 --- a/pdns/dnsdistdist/dnsdist-lua.cc +++ b/pdns/dnsdistdist/dnsdist-lua.cc @@ -559,6 +559,15 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) getOptionalValue(vars, "ktls", config.d_tlsParams.d_ktls); getOptionalValue(vars, "subjectName", config.d_tlsSubjectName); + if (vars->count("keyLogFile") > 0) { +#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK + getOptionalValue(vars, "keyLogFile", config.d_tlsParams.d_keyLogFile); +#else + errlog("TLS Key logging has been enabled using the 'keyLogFile' parameter to newServer(), but this version of OpenSSL does not support it"); + g_outputBuffer = "TLS Key logging has been enabled using the 'keyLogFile' parameter to newServer(), but this version of OpenSSL does not support it"; +#endif + } + if (getOptionalValue(vars, "subjectAddr", valueStr) > 0) { try { ComboAddress addr(valueStr); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index cd2b4d3fc4d7..85df548d8b07 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -749,6 +749,7 @@ Servers ``proxyProtocolAdvertiseTLS`` ``bool`` "Whether to set the SSL Proxy Protocol TLV in the proxy protocol payload sent to the backend if the query was received over an encrypted channel (DNSCrypt, DoQ, DoH or DoT). Requires ``useProxyProtocol=true``. Default is false." ``xskSockets`` ``array`` "An array of :class:`XskSocket` objects to enable ``XSK`` / ``AF_XDP`` support for this backend. See :doc:`../advanced/xsk` for more information." ``MACAddr`` ``str`` "When the ``xskSocket`` option is set, this parameter can be used to specify the destination MAC address to use to reach the backend. If this options is not specified, dnsdist will try to get it from the IP of the backend by looking into the system's MAC address table, but it will fail if the corresponding MAC address is not present." + ``keyLogFile`` ``str`` "Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. Note that this feature requires OpenSSL >= 1.1.1." .. function:: getServer(index) -> Server diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 6fb5b2939cdc..8b91a2bbe27f 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1503,7 +1503,7 @@ static void setupTLSContext(DOHAcceptContext& acceptCtx, libssl_set_error_counters_callback(ctx, &counters); if (!tlsConfig.d_keyLogFile.empty()) { - acceptCtx.d_keyLogFile = libssl_set_key_log_file(ctx, tlsConfig.d_keyLogFile); + acceptCtx.d_keyLogFile = libssl_set_key_log_file(ctx.get(), tlsConfig.d_keyLogFile); } h2o_ssl_register_alpn_protocols(ctx.get(), h2o_http2_alpn_protocols); diff --git a/pdns/libssl.cc b/pdns/libssl.cc index 2493f73d1d0b..8672ffc97b6b 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -1110,7 +1110,7 @@ static void libssl_key_log_file_callback(const SSL* ssl, const char* line) } #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */ -pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr& ctx, const std::string& logFile) +pdns::UniqueFilePtr libssl_set_key_log_file(SSL_CTX* ctx, const std::string& logFile) { #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK auto filePtr = pdns::openFileForWriting(logFile, 0600, false, true); @@ -1118,8 +1118,8 @@ pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr, std::vector> libssl_init_server_context(const TLSConfig& config, std::map& ocspResponses); -pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr& ctx, const std::string& logFile); +pdns::UniqueFilePtr libssl_set_key_log_file(SSL_CTX* ctx, const std::string& logFile); /* called in a server context, to select an ALPN value advertised by the client if any */ void libssl_set_alpn_select_callback(SSL_CTX* ctx, int (*cb)(SSL* s, const unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* arg), void* arg); diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index cb9d480919f1..0286b524db6e 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -675,7 +675,7 @@ class OpenSSLTLSIOCtx: public TLSCtx, public std::enable_shared_from_thisd_tlsCtx.get(), alpnServerSelectCallback, this); if (!frontend.d_tlsConfig.d_keyLogFile.empty()) { - d_feContext->d_keyLogFile = libssl_set_key_log_file(d_feContext->d_tlsCtx, frontend.d_tlsConfig.d_keyLogFile); + d_feContext->d_keyLogFile = libssl_set_key_log_file(d_feContext->d_tlsCtx.get(), frontend.d_tlsConfig.d_keyLogFile); } try { @@ -776,6 +776,10 @@ class OpenSSLTLSIOCtx: public TLSCtx, public std::enable_shared_from_this> d_alpnProtos; // store the supported ALPN protocols, so that the server can select based on what the client sent std::shared_ptr d_tlsCtx{nullptr}; // client context, on a server-side the context is stored in d_feContext->d_tlsCtx std::unique_ptr d_feContext{nullptr}; + pdns::UniqueFilePtr d_keyLogFile{nullptr}; bool d_ktls{false}; }; diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index 742431da4ad8..782aada4e2a2 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -582,6 +582,7 @@ struct TLSContextParameters std::string d_ciphers; std::string d_ciphers13; std::string d_caStore; + std::string d_keyLogFile; TLSFrontend::ALPN d_alpn{TLSFrontend::ALPN::Unset}; bool d_validateCertificates{true}; bool d_releaseBuffers{true};