From: Otto Moerbeek Date: Mon, 6 Oct 2025 11:11:31 +0000 (+0200) Subject: Allow runtime setting of TLS config tables by using rec_control reload-yaml X-Git-Tag: rec-5.4.0-alpha1~190^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6170ba077ff85ccb5b69375582c6cdd92e57d93;p=thirdparty%2Fpdns.git Allow runtime setting of TLS config tables by using rec_control reload-yaml Signed-off-by: Otto Moerbeek --- diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index bdef68605b..f272dff790 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2124,6 +2124,7 @@ static int serviceMain(Logr::log_t log) } g_maxCacheEntries = ::arg().asNum("max-cache-entries"); + cerr << "CALL LUACONFIG" << endl; auto luaResult = luaconfig(false); if (luaResult.d_ret != 0) { log->error(Logr::Error, luaResult.d_str, "Cannot load Lua or equivalent YAML configuration"); @@ -2240,7 +2241,6 @@ static int serviceMain(Logr::log_t log) TCPOutConnectionManager::s_maxIdlePerAuth = ::arg().asNum("tcp-out-max-idle-per-auth"); TCPOutConnectionManager::s_maxQueries = ::arg().asNum("tcp-out-max-queries"); TCPOutConnectionManager::s_maxIdlePerThread = ::arg().asNum("tcp-out-max-idle-per-thread"); - TCPOutConnectionManager::setupOutgoingTLSTables(); g_gettagNeedsEDNSOptions = ::arg().mustDo("gettag-needs-edns-options"); diff --git a/pdns/recursordist/rec-rust-lib/cxxsupport.cc b/pdns/recursordist/rec-rust-lib/cxxsupport.cc index b6bde5d652..cfe7a7dfaf 100644 --- a/pdns/recursordist/rec-rust-lib/cxxsupport.cc +++ b/pdns/recursordist/rec-rust-lib/cxxsupport.cc @@ -1396,6 +1396,7 @@ bool pdns::settings::rec::luaItemSet(const pdns::rust::settings::rec::Recursorse alldefault = alldefault && settings.recordcache.zonetocaches.empty(); alldefault = alldefault && settings.recursor.allowed_additional_qtypes.empty(); alldefault = alldefault && settings.incoming.proxymappings.empty(); + alldefault = alldefault && settings.outgoing.tls_configurations.empty(); // actually not a Lua item, but very much alike return !alldefault; } diff --git a/pdns/recursordist/rec-rust-lib/table.py b/pdns/recursordist/rec-rust-lib/table.py index d28db2e752..fda1dc3be0 100644 --- a/pdns/recursordist/rec-rust-lib/table.py +++ b/pdns/recursordist/rec-rust-lib/table.py @@ -3653,6 +3653,6 @@ Sequence of OutgoingTLSConfiguration.` ''', 'skip-old' : 'No equivalent old style setting', 'versionadded': '5.4.0', - 'runtime': ['reload-lua-config', 'reload-yaml'], # XXX + 'runtime': ['reload-lua-config', 'reload-yaml'], }, ] diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 775d30db8f..26072b654d 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -73,7 +73,7 @@ static thread_local std::unique_ptr t_tcpClientCounts = std:: static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var); -#if 1 +#if 0 #define TCPLOG(tcpsock, x) \ do { \ cerr << []() { timeval t; gettimeofday(&t, nullptr); return t.tv_sec % 10 + t.tv_usec/1000000.0; }() << " FD " << (tcpsock) << ' ' << x; \ diff --git a/pdns/recursordist/rec-tcpout.cc b/pdns/recursordist/rec-tcpout.cc index 5fb4076195..c090e1fab6 100644 --- a/pdns/recursordist/rec-tcpout.cc +++ b/pdns/recursordist/rec-tcpout.cc @@ -86,52 +86,60 @@ TCPOutConnectionManager::Connection TCPOutConnectionManager::get(const endpoints return Connection{}; } -static SuffixMatchTree s_suffixToConfig; -static NetmaskTree s_netmaskToConfig; +struct OutgoingTLSConfigTable { + SuffixMatchTree d_suffixToConfig; + NetmaskTree d_netmaskToConfig; +}; -void TCPOutConnectionManager::setupOutgoingTLSTables() +static LockGuarded s_outgoingTLSConfigTable; + +void TCPOutConnectionManager::setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings) { - auto settings = g_yamlStruct.lock(); - auto& vec = settings->outgoing.tls_configurations; + auto& vec = settings.outgoing.tls_configurations; + auto table = s_outgoingTLSConfigTable.lock(); + table->d_suffixToConfig = SuffixMatchTree(); // no clear? + table->d_netmaskToConfig.clear(); for (const auto& entry : vec) { for (const auto& element : entry.suffixes) { DNSName name = DNSName(std::string(element)); auto copy = entry; - s_suffixToConfig.add(name, std::move(copy)); + table->d_suffixToConfig.add(name, std::move(copy)); } for (const auto& element : entry.subnets) { - s_netmaskToConfig.insert(std::string(element)).second = entry; + table->d_netmaskToConfig.insert(std::string(element)).second = entry; } } } std::shared_ptr TCPOutConnectionManager::getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string &subjectAddress) { - pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr}; - - if (auto* node = s_netmaskToConfig.lookup(address); node != nullptr) { - config = &node->second; - } - else if (auto* found = s_suffixToConfig.lookup(DNSName(name)); found != nullptr) { - config = found; - } - TLSContextParameters tlsParams; tlsParams.d_provider = "openssl"; tlsParams.d_validateCertificates = false; - if (config != nullptr) { - tlsParams.d_provider = std::string(config->provider); - tlsParams.d_validateCertificates = config->validate_certificate; - tlsParams.d_caStore = std::string(config->ca_store); - if (!config->subject_name.empty()) { - subjectName = std::string(config->subject_name); - }; - if (!config->subject_address.empty()) { - subjectAddress = std::string(config->subject_address); - }; - verboseLogging = config->verbose_logging = true; - tlsParams.d_ciphers = std::string(config->ciphers); - tlsParams.d_ciphers13 = std::string(config->ciphers_tls_13); + const pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr}; + + { + auto table = s_outgoingTLSConfigTable.lock(); + if (auto* node = table->d_netmaskToConfig.lookup(address); node != nullptr) { + config = &node->second; + } + else if (const auto* found = table->d_suffixToConfig.lookup(DNSName(name)); found != nullptr) { + config = found; + } + if (config != nullptr) { + tlsParams.d_provider = std::string(config->provider); + tlsParams.d_validateCertificates = config->validate_certificate; + tlsParams.d_caStore = std::string(config->ca_store); + if (!config->subject_name.empty()) { + subjectName = std::string(config->subject_name); + }; + if (!config->subject_address.empty()) { + subjectAddress = std::string(config->subject_address); + }; + verboseLogging = config->verbose_logging; + tlsParams.d_ciphers = std::string(config->ciphers); + tlsParams.d_ciphers13 = std::string(config->ciphers_tls_13); + } } return ::getTLSContext(tlsParams); } diff --git a/pdns/recursordist/rec-tcpout.hh b/pdns/recursordist/rec-tcpout.hh index 4a954b2c77..23fc5723f3 100644 --- a/pdns/recursordist/rec-tcpout.hh +++ b/pdns/recursordist/rec-tcpout.hh @@ -25,6 +25,11 @@ #include "iputils.hh" #include "tcpiohandler.hh" +namespace pdns::rust::settings::rec +{ +struct Recursorsettings; +} + class TCPOutConnectionManager { public: @@ -69,7 +74,7 @@ public: return new uint64_t(size()); // NOLINT(cppcoreguidelines-owning-memory): it's the API } - static void setupOutgoingTLSTables(); + static void setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings); static std::shared_ptr getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress); private: diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index b28f5d36d1..d87f0ba327 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -2020,6 +2020,7 @@ RecursorControlChannel::Answer luaconfig(bool broadcast) // Initial proxy mapping g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique(proxyMapping); } + TCPOutConnectionManager::setupOutgoingTLSConfigTables(settings); return {0, "Reloaded dynamic part of YAML configuration\n"}; }