]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Allow setting keyLogFile to DoT/DoH backends
authorKarel Bilek <kb@karelbilek.com>
Mon, 9 Dec 2024 08:44:51 +0000 (09:44 +0100)
committerKarel Bilek <kb@karelbilek.com>
Mon, 9 Dec 2024 12:51:58 +0000 (13:51 +0100)
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/docs/reference/config.rst
pdns/dnsdistdist/doh.cc
pdns/libssl.cc
pdns/libssl.hh
pdns/tcpiohandler.cc
pdns/tcpiohandler.hh

index fa0940a988a2bdaaf7b3ea465661a91874933f1f..646b1f23942aeecf05e28b4387eb3840ad3b3c64 100644 (file)
@@ -559,6 +559,15 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
                          getOptionalValue<bool>(vars, "ktls", config.d_tlsParams.d_ktls);
                          getOptionalValue<std::string>(vars, "subjectName", config.d_tlsSubjectName);
 
+                         if (vars->count("keyLogFile") > 0) {
+#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
+                           getOptionalValue<std::string>(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<std::string>(vars, "subjectAddr", valueStr) > 0) {
                            try {
                              ComboAddress addr(valueStr);
index cd2b4d3fc4d7b0916e2b09026f330f9baa9aa5be..85df548d8b078297ee7a650395cfc7c53d5b92d3 100644 (file)
@@ -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
 
index 6fb5b2939cdc2d256e34c58d5fbab6e235d1a761..8b91a2bbe27f95fa58cd05e090bc91d0f0daeb6e 100644 (file)
@@ -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);
index 2493f73d1d0b5c3d43eaa57bd1ec230bfc9c56af..8672ffc97b6b4643acb71d26452f67cb319fb216 100644 (file)
@@ -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<SSL_CTX, decltype(&SSL_CTX_free)>& 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<SSL_CTX, decltype(&S
     auto error = errno;
     throw std::runtime_error("Error opening file " + logFile + " for writing: " + stringerror(error));
   }
-  SSL_CTX_set_ex_data(ctx.get(), s_keyLogIndex, filePtr.get());
-  SSL_CTX_set_keylog_callback(ctx.get(), &libssl_key_log_file_callback);
+  SSL_CTX_set_ex_data(ctx, s_keyLogIndex, filePtr.get());
+  SSL_CTX_set_keylog_callback(ctx, &libssl_key_log_file_callback);
   return filePtr;
 #else
   return pdns::UniqueFilePtr(nullptr);
index d927f7bfa2b58f53821ec58ee450a5e3ad6d2236..3d3e5a8eba48e49fda9e5917ba5c607d99ddf2db 100644 (file)
@@ -158,7 +158,7 @@ bool libssl_set_min_tls_version(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)
 std::pair<std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>, std::vector<std::string>> libssl_init_server_context(const TLSConfig& config,
                                                                                                             std::map<int, std::string>& ocspResponses);
 
-pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& 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);
index cb9d480919f1f03af2f35691c47a97cac22f7276..0286b524db6e6bdf12476aa1ad4f1912cbedf0f7 100644 (file)
@@ -675,7 +675,7 @@ public:
     libssl_set_alpn_select_callback(d_feContext->d_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 @@ public:
     SSL_CTX_set_session_cache_mode(d_tlsCtx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
     SSL_CTX_sess_set_new_cb(d_tlsCtx.get(), &OpenSSLTLSIOCtx::newTicketFromServerCb);
 
+    if (!params.d_keyLogFile.empty()) {
+      d_keyLogFile = libssl_set_key_log_file(d_tlsCtx.get(), params.d_keyLogFile);
+    }
+
     libssl_set_alpn_protos(d_tlsCtx.get(), getALPNVector(params.d_alpn, true));
 
 #ifdef SSL_MODE_RELEASE_BUFFERS
@@ -950,6 +954,7 @@ private:
   const std::vector<std::vector<uint8_t>> d_alpnProtos; // store the supported ALPN protocols, so that the server can select based on what the client sent
   std::shared_ptr<SSL_CTX> d_tlsCtx{nullptr}; // client context, on a server-side the context is stored in d_feContext->d_tlsCtx
   std::unique_ptr<OpenSSLFrontendContext> d_feContext{nullptr};
+  pdns::UniqueFilePtr d_keyLogFile{nullptr};
   bool d_ktls{false};
 };
 
index 742431da4ad8b5d7304227fc5a67878cbcc1ce1e..782aada4e2a28de9fb0154bdacc351e6afa8c0a8 100644 (file)
@@ -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};