From 331bcdd5314378bfa269578cdfe3d84c52642107 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Fri, 3 Jun 2016 09:44:02 +0200 Subject: [PATCH] recursor: implement runtime trust anchor management --- docs/manpages/rec_control.1.md | 10 ++++ pdns/rec_channel_rec.cc | 100 +++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/docs/manpages/rec_control.1.md b/docs/manpages/rec_control.1.md index dc074d440..da0b383dc 100644 --- a/docs/manpages/rec_control.1.md +++ b/docs/manpages/rec_control.1.md @@ -46,6 +46,9 @@ To dump the cache to disk, execute: add-nta *DOMAIN* [*REASON*] : Add a Negative Trust Anchor for *DOMAIN*, suffixed optionally with *REASON*. +add-ta *DOMAIN* *DSRECORD* +: Add a Trust Anchor for *DOMAIN* with DS record data *DSRECORD*. + current-queries : Shows the currently active queries. @@ -53,6 +56,10 @@ clear-nta *DOMAIN*... : Remove Negative Trust Anchor for one or more *DOMAIN*s. Set domain to `'*'` to remove all NTA's. +clear-ta [*DOMAIN*]... +: Remove Trust Anchor for one or more *DOMAIN*s. Note that removing the root + trust anchor is not possible. + dump-cache *FILENAME* : Dumps the entire cache to *FILENAME*. This file should not exist already, PowerDNS will refuse to overwrite it. While @@ -78,6 +85,9 @@ get-all get-ntas : Get a list of the currently configured Negative Trust Anchors. +get-tas +: Get a list of the currently configured Trust Anchors. + get-parameter *KEY* [*KEY*]... : Retrieves the specified configuration parameter(s). diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index e1e0dd803..5568712b3 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -430,6 +430,91 @@ static string getNTAs() return ret; } +template +string doAddTA(T begin, T end) +{ + if(begin == end) + return "No TA specified, doing nothing\n"; + + DNSName who; + try { + who = DNSName(*begin); + } + catch(std::exception &e) { + string ret("Can't add Trust Anchor: "); + ret += e.what(); + ret += "\n"; + return ret; + } + begin++; + + string what(""); + while (begin != end) { + what += *begin + " "; + begin++; + } + + try { + g_luaconfs.modify([who, what](LuaConfigItems& lci) { + lci.dsAnchors[who] = *std::unique_ptr(dynamic_cast(DSRecordContent::make(what))); + }); + broadcastAccFunction(boost::bind(pleaseWipePacketCache, who, true)); + return "Added Trust Anchor for " + who.toStringRootDot() + " with data " + what + "\n"; + } + catch(std::exception &e) { + return "Unable to add Trust Anchor for " + who.toStringRootDot() + ": " + e.what() + "\n"; + } +} + +template +string doClearTA(T begin, T end) +{ + if(begin == end) + return "No Trust Anchor to clear\n"; + + vector toRemove; + DNSName who; + while (begin != end) { + try { + who = DNSName(*begin); + } + catch(std::exception &e) { + string ret("Error: "); + ret += e.what(); + ret += ". No Anchors removed\n"; + return ret; + } + if (who.isRoot()) + return "Refusing to remove root Trust Anchor, no Anchors removed\n"; + toRemove.push_back(who); + begin++; + } + + string removed(""); + bool first(true); + for (auto const &who : toRemove) { + g_luaconfs.modify([who](LuaConfigItems& lci) { + lci.dsAnchors.erase(who); + }); + broadcastAccFunction(boost::bind(pleaseWipePacketCache, who, true)); + if (!first) { + first = false; + removed += ","; + } + removed += " " + who.toStringRootDot(); + } + return "Removed Trust Anchor(s) for" + removed + "\n"; +} + +static string getTAs() +{ + string ret("Configured Trust Anchors:\n"); + auto luaconf = g_luaconfs.getLocal(); + for (auto anchor : luaconf->dsAnchors) + ret += anchor.first.toLogString() + "\t" + anchor.second.getZoneRepresentation() + "\n"; + return ret; +} + template string setMinimumTTL(T begin, T end) { @@ -991,14 +1076,17 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP if(cmd=="help") return "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n" +"add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n" "current-queries show currently active queries\n" "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n" +"clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n" "dump-cache dump cache contents to the named file\n" "dump-edns[status] dump EDNS status to the named file\n" "dump-nsspeeds dump nsspeeds statistics to the named file\n" "get [key1] [key2] .. get specific statistics\n" "get-all get all statistics\n" "get-ntas get all configured Negative Trust Anchors\n" +"get-tas get all configured Trust Anchors\n" "get-parameter [key1] [key2] .. get configuration parameters\n" "get-qtypelist get QType statistics\n" " notice: queries from cache aren't being counted yet\n" @@ -1151,6 +1239,18 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP if(cmd=="get-ntas") { return getNTAs(); } + + if(cmd=="add-ta") { + return doAddTA(begin, end); + } + + if(cmd=="clear-ta") { + return doClearTA(begin, end); + } + + if(cmd=="get-tas") { + return getTAs(); + } return "Unknown command '"+cmd+"', try 'help'\n"; } -- 2.40.0