From: Remi Gacogne Date: Mon, 25 Sep 2023 10:09:19 +0000 (+0200) Subject: dnsdist: Add an option to log DoQ TLS keying material to a file X-Git-Tag: rec-5.0.0-alpha2~6^2~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1cba32b066297d27f64dc1075434f70762346baf;p=thirdparty%2Fpdns.git dnsdist: Add an option to log DoQ TLS keying material to a file --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 2c794ec9b5..0edf61947b 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2515,6 +2515,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); + getOptionalValue(vars, "keyLogFile", frontend->d_keyLogFile); { std::string valueStr; if (getOptionalValue(vars, "congestionControlAlgo", valueStr) > 0) { diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 354f477f00..2a68f20e5e 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -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]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index ed1548ce7a..2a16a052a2 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -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> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) +static std::optional> 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> 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; } diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 9d318c9aac..70c69d324f 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -45,11 +45,13 @@ struct DOQFrontend DOQFrontend& operator=(DOQFrontend&&) = delete; ~DOQFrontend(); + void setup(); + std::unique_ptr 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