]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add an option to log DoQ TLS keying material to a file
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 25 Sep 2023 10:09:19 +0000 (12:09 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 9 Oct 2023 11:38:00 +0000 (13:38 +0200)
pdns/dnsdist-lua.cc
pdns/dnsdistdist/docs/reference/config.rst
pdns/dnsdistdist/doq.cc
pdns/dnsdistdist/doq.hh

index 2c794ec9b55fc14122d2274332f86b8ca9f2edae..0edf61947b0516c6e0a95b4dc387229ef2de3b99 100644 (file)
@@ -2515,6 +2515,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       }
       getOptionalValue<int>(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize);
       getOptionalValue<int>(vars, "idleTimeout", frontend->d_idleTimeout);
+      getOptionalValue<std::string>(vars, "keyLogFile", frontend->d_keyLogFile);
       {
         std::string valueStr;
         if (getOptionalValue<std::string>(vars, "congestionControlAlgo", valueStr) > 0) {
index 354f477f00d0d216f4d1a0234b2f6945dec7b9ce..2a68f20e5e12d032ed1f45dbc56c629b1fec3947 100644 (file)
@@ -191,7 +191,8 @@ Listen Sockets
   * ``idleTimeout=5``: int - Set the idle timeout, in seconds.
   * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0.
   * ``maxInFlight=0``: int - Maximum number of in-flight queries. The default is 0, which disables out-of-order processing.
-  * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr``
+  * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr``.
+  * ``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.
 
 .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options])
 
index ed1548ce7a742fd1a73b517fca065f57447fd839..2a16a052a29830935026c6f9e8c6d7c511aaf964 100644 (file)
@@ -327,6 +327,9 @@ void DOQFrontend::setup()
   // The number of total bytes of incoming stream data to be buffered for the whole connection
   // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data
   quiche_config_set_initial_max_data(config.get(), 8192 * d_maxInFlight);
+  if (!d_keyLogFile.empty()) {
+    quiche_config_log_keys(config.get());
+  }
 
   auto algo = DOQFrontend::s_available_cc_algorithms.find(d_ccAlgo);
   if (algo != DOQFrontend::s_available_cc_algorithms.end()) {
@@ -482,7 +485,7 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description)
   }
 }
 
-static std::optional<std::reference_wrapper<Connection>> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer)
+static std::optional<std::reference_wrapper<Connection>> createConnection(const DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer)
 {
   auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(),
                                                    originalDestinationID.data(), originalDestinationID.size(),
@@ -490,8 +493,13 @@ static std::optional<std::reference_wrapper<Connection>> createConnection(Quiche
                                                    local.getSocklen(),
                                                    (struct sockaddr*)&peer,
                                                    peer.getSocklen(),
-                                                   config.get()),
+                                                   config.config.get()),
                                      quiche_conn_free);
+
+  if (config.df && !config.df->d_keyLogFile.empty()) {
+    quiche_conn_set_keylog_path(quicheConn.get(), config.df->d_keyLogFile.c_str());
+  }
+
   auto conn = Connection(peer, std::move(quicheConn));
   auto pair = s_connections.emplace(serverSideID, std::move(conn));
   return pair.first->second;
@@ -809,7 +817,7 @@ void doqThread(ClientState* cs)
           }
 
           DEBUGLOG("Creating a new connection");
-          conn = createConnection(frontend->d_server_config->config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client);
+          conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client);
           if (!conn) {
             continue;
           }
index 9d318c9aacfeac98ff0867620eb178a8c95acdc4..70c69d324f6740e4468db2e88c5c8c17cc82c10a 100644 (file)
@@ -45,11 +45,13 @@ struct DOQFrontend
   DOQFrontend& operator=(DOQFrontend&&) = delete;
   ~DOQFrontend();
 
+  void setup();
+
   std::unique_ptr<DOQServerConfig> d_server_config{nullptr};
   TLSConfig d_tlsConfig;
   ComboAddress d_local;
+  std::string d_keyLogFile;
 
-  void setup();
 #ifdef __linux__
   // On Linux this gives us 128k pending queries (default is 8192 queries),
   // which should be enough to deal with huge spikes