From: Otto Moerbeek Date: Tue, 6 Jun 2023 14:11:59 +0000 (+0200) Subject: rec: implement a way to disable specific DNSSEC algorithms X-Git-Tag: rec-4.10.0-alpha0~2^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04cee9810cab8a785e381fd636dc674bbef9c959;p=thirdparty%2Fpdns.git rec: implement a way to disable specific DNSSEC algorithms This could be needed when runing RHEL9, to avoid having zones signed with algo 5 or 7 going Bogus. RHEL9 does not support these algorithms, unless the globalsecurity policy is modified. --- diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 5a8e3cd96f..c2d76a35d0 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -453,10 +453,25 @@ string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, c return toHash; } +std::unordered_set DNSCryptoKeyEngine::s_switchedOff; + +bool DNSCryptoKeyEngine::isAlgorithmSwitchedOff(unsigned int algo) +{ + return s_switchedOff.count(algo) != 0; +} + +void DNSCryptoKeyEngine::switchOffAlgorithm(unsigned int algo) +{ + s_switchedOff.insert(algo); +} + bool DNSCryptoKeyEngine::isAlgorithmSupported(unsigned int algo) { + if (isAlgorithmSwitchedOff(algo)) { + return false; + } const makers_t& makers = getMakers(); - makers_t::const_iterator iter = makers.find(algo); + auto iter = makers.find(algo); return iter != makers.cend(); } diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index c6ddb5bc0e..c1628fca1b 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -166,6 +166,8 @@ class DNSCryptoKeyEngine static std::unique_ptr makeFromPublicKeyString(unsigned int algorithm, const std::string& raw); static std::unique_ptr make(unsigned int algorithm); static bool isAlgorithmSupported(unsigned int algo); + static bool isAlgorithmSwitchedOff(unsigned int algo); + static void switchOffAlgorithm(unsigned int algo); static bool isDigestSupported(uint8_t digest); using maker_t = std::unique_ptr (unsigned int); @@ -189,6 +191,7 @@ class DNSCryptoKeyEngine static allmakers_t s_allmakers; return s_allmakers; } + static std::unordered_set s_switchedOff; protected: const unsigned int d_algorithm; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 416609fa70..563dab5b15 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1452,6 +1452,32 @@ static int initDNSSEC(Logr::log_t log) g_dnssecLogBogus = ::arg().mustDo("dnssec-log-bogus"); g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations"); + + vector nums; + if (!::arg()["dnssec-disabled-algorithms"].empty()) { + stringtok(nums, ::arg()["dnssec-disabled-algorithms"], ", "); + for (auto num: nums) { + DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); + } + } else { + // Auto determine algos to switch off + } + if (!nums.empty()) { + if (!g_slogStructured) { + g_log << Logger::Warning << "Disabled DNSSEC algorithm: "; + for (auto i = nums.begin(); i != nums.end(); ++i) { + if (i != nums.begin()) { + g_log << Logger::Warning << ", "; + } + g_log << Logger::Warning << *i; + } + g_log << Logger::Warning << endl; + } + else { + log->info(Logr::Notice, "Disabled DNSSEC algorithms", "algorithms", Logging::IterLoggable(nums.begin(), nums.end())); + } + } + return 0; } @@ -2746,6 +2772,7 @@ static void initArgs() ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; ::arg().set("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60"; + ::arg().set("dnssec-disabled-algorithms", "List of DNSSEC algorithm numbers that are considered unsupported") = ""; ::arg().set("daemon", "Operate as a daemon") = "no"; ::arg().setSwitch("write-pid", "Write a PID file") = "yes"; ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6";