From: Otto Date: Tue, 5 Oct 2021 07:42:19 +0000 (+0200) Subject: Followup on ZoneToCache and fix #10246: document local root config (rfc8806) X-Git-Tag: auth-4.6.0-alpha1~4^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b5314b99e70575aad1999f6fa5ba5e34b909891;p=thirdparty%2Fpdns.git Followup on ZoneToCache and fix #10246: document local root config (rfc8806) --- diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 899fe50e90..54651f2456 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -738,6 +738,7 @@ Inno innodb inode installable +Internic interop interoperability interoperation diff --git a/pdns/recursordist/docs/lua-config/ztc.rst b/pdns/recursordist/docs/lua-config/ztc.rst new file mode 100644 index 0000000000..a636c92d54 --- /dev/null +++ b/pdns/recursordist/docs/lua-config/ztc.rst @@ -0,0 +1,75 @@ +.. _ztc: + +Zone to Cache +------------- + +Zone to Cache is a function to load a zone to the Recursor cache periodically or once at startup. +This allows the Recursor to have an always hot cache for these zones. +The zone to cache can be retrieved via zone transfer (AXFR format) or read from a zone file retrieved via http, https or a local file. + +Example +^^^^^^^ +To load the root zone from Internic into the recursor once at startup and when the Lua config is reloaded: + +.. code-block:: Lua + + zoneToCache(".", "url", 'https://www.internic.net/domain/root.zone', { refreshPeriod = 0 }) + +Configuration +^^^^^^^^^^^^^ +.. function:: zoneToCache(zone, method, source [, settings ]) + + .. versionadded:: 4.6.0 + + Load a zone and put it into the Recursor cache periodically. + + :param str zone: The name of the zone to load + :param str method: One of ``"axfr"``, ``"url"`` or ``"file"`` + :param str source: A string representing an IP address (when using the ``axfr`` method), URL (when using the ``url`` method) or path name (when using the ``file`` method) + :param table settings: A table of settings, see below + + +Zone to Cache settings +^^^^^^^^^^^^^^^^^^^^^^ + +These options can be set in the ``settings`` of :func:`zoneToCache`. + +timeout +~~~~~~~ +The maximum time (in seconds) a retrieval using the ``axfr`` or ``url`` method may take. +Default is 20 seconds. + +tsigname +~~~~~~~~ +The name of the TSIG key to authenticate to the server when using the ``axfr`` method +When this is set, `tsigalgo`_ and `tsigsecret`_ must also be set. + +tsigalgo +~~~~~~~~ +The name of the TSIG algorithm (like 'hmac-md5') used + +tsigsecret +~~~~~~~~~~ +Base64 encoded TSIG secret + +refreshPeriod +~~~~~~~~~~~~~ +An integer describing the interval (in seconds) to wait between retrievals. +A value of zero means the retrieval is done once at startup and on Lua configuration reload. +By default, the refresh value is 86400 (24 hours). + +retryOnErrorPeriod +~~~~~~~~~~~~~~~~~~ +An integer describing the interval (in seconds) to wait before retrying a failed transfer. +By default 60 is used. + +maxReceivedMBytes +~~~~~~~~~~~~~~~~~ +The maximum size in megabytes of an update via the ``axfr`` or ``url`` methods, to prevent resource exhaustion. +The default value of 0 means no restriction. + +localAddress +~~~~~~~~~~~~ +The source IP address to use when transferring using the ``axfr`` or ``url`` methods. +When unset, :ref:`setting-query-local-address` is used. + diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index b8b9ca663b..bbebb3405d 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -134,6 +134,30 @@ If you operate an anycast pool of machines, make them share the TCP Fast Open Ke To determine a good value for the :ref:`setting-tcp-fast-open` setting, watch the ``TCPFastOpenListenOverflow`` metric. If this value increases often, the value might be too low for your traffic, but note that increasing it will use kernel resources. +Running with a local root zone +----------------------------- +Running with a local root zone as described in :rfc:`8806` can help reduce traffic to the root servers and reduce response times for clients. +Since 4.6.0 PowerDNS Recursor supports two ways of doing this. + +Running a local Authoritative Server for the root zone + +- The first method is to have a local Authoritative Server that has a copy of the root zone and forward queries to it. + Setting up an PowerDNS Authoritative Server to serve a copy of the root zone looks like: + + pdnsutil create-secondary-zone . ip1 ip2 + + where ``ip1`` and ``ip2`` are servers willing to serve an AXFR for the root zone; :rfc:`8806` contains a list of candidates in appendix A. The Authoritative Server will periodically make sure its copy of the root zone is up-to-date. + The next step is to configure a forward zone to the IP ``ip`` of the Authoritative Server in the settings file or the Recursor: + + forward-zones=.=ip + + The Recursor will use the Authoritative Server to ask questions about the root zone, but if it learns about delegations still follow those. + Multiple Recursors can use this Authoritative Server. + +- The second method is to cache the root zone as described in :ref:`ztc`. + Here each Recursor will download and fill its cache with the contents of the root zone. + Depending on the ``timeout`` parameter, this will be done once or periodically. + Refer to :ref:`ztc` for details. Recursor Caches --------------- diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 6fdf7568d9..da16345e3f 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -39,8 +39,10 @@ struct ZoneData { - ZoneData(shared_ptr& log) : - d_log(log) {} + ZoneData(shared_ptr& log, const std::string& zone) : + d_log(log), + d_zone(zone), + d_now(time(nullptr)) {} // Potentially the two fields below could be merged into a single map. ATM it is not clear to me // if that would make the code easier to read. @@ -50,9 +52,9 @@ struct ZoneData // Maybe use a SuffixMatchTree? std::set d_delegations; - time_t d_now; - DNSName d_zone; shared_ptr& d_log; + DNSName d_zone; + time_t d_now; bool isRRSetAuth(const DNSName& qname, QType qtype) const; void parseDRForCache(DNSRecord& dr); @@ -182,6 +184,8 @@ static std::vector getURL(const RecZoneToCache::Config& config) while (std::getline(stream, line)) { lines.push_back(line); } +#else + throw std::runtime_error("url method configured but libcurl not compiled in"); #endif return lines; } @@ -191,8 +195,6 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config, uint64_t config if (config.d_sources.size() > 1) { d_log->info("Multiple sources not yet supported, using first"); } - d_zone = DNSName(config.d_zone); - d_now = time(nullptr); // We do not do validation, it will happen on-demand if an Indeterminate record is encountered when the caches are queried // First scan all records collecting info about delegations ans sigs @@ -275,7 +277,7 @@ void RecZoneToCache::ZoneToCache(RecZoneToCache::Config config, uint64_t configG time_t refresh = config.d_retryOnError; try { - ZoneData data(log); + ZoneData data(log, config.d_zone); data.ZoneToCache(config, configGeneration); if (luaconfsLocal->generation != configGeneration) { log->info("A more recent configuration has been found, stopping the old update thread");