From: Otto Moerbeek Date: Fri, 17 Nov 2023 10:24:48 +0000 (+0100) Subject: rec: disallow (by answering Refused) RD=0 by default X-Git-Tag: rec-5.0.0-rc1~2^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd3a04692b09cc3511be349aeb350fbee0682edd;p=thirdparty%2Fpdns.git rec: disallow (by answering Refused) RD=0 by default Fixes #13386 --- diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 9435f555e5..7ecd38b7bd 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -71,6 +71,7 @@ unsigned int g_paddingTag; PaddingMode g_paddingMode; uint16_t g_udpTruncationThreshold; std::atomic g_quiet; +bool g_allowNoRD; bool g_logCommonErrors; bool g_reusePort{false}; bool g_gettagNeedsEDNSOptions{false}; @@ -1154,7 +1155,14 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } if (!comboWriter->d_mdp.d_header.rd) { - resolver.setCacheOnly(); + if (g_allowNoRD) { + resolver.setCacheOnly(); + } + else { + ret.clear(); + res = RCode::Refused; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) + } } if (comboWriter->d_luaContext) { diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 9cc1cde07a..ed853cfbac 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2100,6 +2100,7 @@ static int serviceMain(Logr::log_t log) g_logRPZChanges = ::arg().mustDo("log-rpz-changes"); g_anyToTcp = ::arg().mustDo("any-to-tcp"); + g_allowNoRD = ::arg().mustDo("allow-no-rd"); g_udpTruncationThreshold = ::arg().asNum("udp-truncation-threshold"); g_lowercaseOutgoing = ::arg().mustDo("lowercase-outgoing"); @@ -2849,313 +2850,6 @@ static void recursorThread() } } -#if 0 -// THIS FUNCTION IS REPLACED BY GENERATED CODE IN settings/cxxsettings-generated.cc -static void initArgs() -{ -#if HAVE_FIBER_SANITIZER - // Asan needs more stack - ::arg().set("stack-size", "stack size per mthread") = "600000"; -#else - ::arg().set("stack-size", "stack size per mthread") = "200000"; -#endif - ::arg().set("stack-cache-size", "Size of the stack cache, per mthread") = "100"; - // This mode forces metrics snap updates and disable root-refresh, to get consistent counters - ::arg().setSwitch("devonly-regression-test-mode", "internal use only") = "no"; - ::arg().set("soa-minimum-ttl", "Don't change") = "0"; - ::arg().setSwitch("no-shuffle", "Don't change") = "off"; - ::arg().set("local-port", "port to listen on") = "53"; - ::arg().set("local-address", "IP addresses to listen on, separated by spaces or commas. Also accepts ports.") = "127.0.0.1"; - ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options") = "no"; - ::arg().set("trace", "if we should output heaps of logging. set to 'fail' to only log failing domains") = "off"; - ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; - ::arg().setSwitch("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().setSwitch("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"; - ::arg().setSwitch("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no"; - ::arg().setSwitch("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes"; - ::arg().setSwitch("log-common-errors", "If we should log rather common errors") = "no"; - ::arg().set("chroot", "switch to chroot jail") = ""; - ::arg().set("setgid", "If set, change group id to this gid for more security" -#ifdef HAVE_SYSTEMD -#define SYSTEMD_SETID_MSG ". When running inside systemd, use the User and Group settings in the unit-file!" - SYSTEMD_SETID_MSG -#endif - ) - = ""; - ::arg().set("setuid", "If set, change user id to this uid for more security" -#ifdef HAVE_SYSTEMD - SYSTEMD_SETID_MSG -#endif - ) - = ""; - ::arg().set("network-timeout", "Wait this number of milliseconds for network i/o") = "1500"; - ::arg().set("threads", "Launch this number of threads") = "2"; - ::arg().set("distributor-threads", "Launch this number of distributor threads, distributing queries to other threads") = "0"; - ::arg().set("processes", "Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)") = "1"; // if we un-experimental this, need to fix openssl rand seeding for multiple PIDs! - ::arg().set("config-name", "Name of this virtual configuration - will rename the binary image") = ""; - ::arg().set("api-config-dir", "Directory where REST API stores config and zones") = ""; - ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API") = ""; - ::arg().setSwitch("webserver", "Start a webserver (for REST API)") = "no"; - ::arg().set("webserver-address", "IP Address of webserver to listen on") = "127.0.0.1"; - ::arg().set("webserver-port", "Port of webserver to listen on") = "8082"; - ::arg().set("webserver-password", "Password required for accessing the webserver") = ""; - ::arg().set("webserver-allow-from", "Webserver access is only allowed from these subnets") = "127.0.0.1,::1"; - ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal"; - ::arg().setSwitch("webserver-hash-plaintext-credentials", "Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime") = "no"; - ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats") = ""; - ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address") = ""; - ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates") = "30"; - ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string") = "pdns"; - ::arg().set("carbon-instance", "If set overwrites the instance name default") = "recursor"; - - ::arg().set("statistics-interval", "Number of seconds between printing of recursor statistics, 0 to disable") = "1800"; - ::arg().setSwitch("quiet", "Suppress logging of questions and answers") = "yes"; - ::arg().set("logging-facility", "Facility to log messages as. 0 corresponds to local0") = ""; - ::arg().set("config-dir", "Location of configuration directory (recursor.conf)") = SYSCONFDIR; - ::arg().set("socket-owner", "Owner of socket") = ""; - ::arg().set("socket-group", "Group of socket") = ""; - ::arg().set("socket-mode", "Permissions for socket") = ""; - - ::arg().set("socket-dir", string("Where the controlsocket will live, ") + LOCALSTATEDIR + "/pdns-recursor when unset and not chrooted" -#ifdef HAVE_SYSTEMD - + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).") - = ""; - auto* runtimeDir = getenv("RUNTIME_DIRECTORY"); // NOLINT(concurrency-mt-unsafe,cppcoreguidelines-pro-type-vararg) - if (runtimeDir != nullptr) { - ::arg().set("socket-dir") = runtimeDir; - } -#else - ) - = ""; -#endif - ::arg().set("query-local-address", "Source IP address for sending queries") = "0.0.0.0"; - ::arg().set("client-tcp-timeout", "Timeout in seconds when talking to TCP clients") = "2"; - ::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads") = "2048"; - ::arg().set("max-tcp-clients", "Maximum number of simultaneous TCP clients") = "128"; - ::arg().set("max-concurrent-requests-per-tcp-connection", "Maximum number of requests handled concurrently per TCP connection") = "10"; - ::arg().set("server-down-max-fails", "Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )") = "64"; - ::arg().set("server-down-throttle-time", "Number of seconds to throttle all queries to a server after being marked as down") = "60"; - ::arg().set("dont-throttle-names", "Do not throttle nameservers with this name or suffix") = ""; - ::arg().set("dont-throttle-netmasks", "Do not throttle nameservers with this IP netmask") = ""; - ::arg().set("non-resolving-ns-max-fails", "Number of failed address resolves of a nameserver to start throttling it, 0 is disabled") = "5"; - ::arg().set("non-resolving-ns-throttle-time", "Number of seconds to throttle a nameserver with a name failing to resolve") = "60"; - - ::arg().set("hint-file", "If set, load root hints from this file") = ""; - ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache") = "1000000"; - ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600"; - ::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600"; - ::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400"; - ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400"; - ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000"; - ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60"; - ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60"; - ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = ""; - ::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000"; - ::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString(); - ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse") = LOCAL_NETS; - ::arg().set("allow-from-file", "If set, load allowed netmasks from this file") = ""; - ::arg().set("allow-notify-for", "If set, NOTIFY requests for these zones will be allowed") = ""; - ::arg().set("allow-notify-for-file", "If set, load NOTIFY-allowed zones from this file") = ""; - ::arg().set("allow-notify-from", "If set, NOTIFY requests from these comma separated netmasks will be allowed") = ""; - ::arg().set("allow-notify-from-file", "If set, load NOTIFY-allowed netmasks from this file") = ""; - ::arg().set("entropy-source", "If set, read entropy from this file") = "/dev/urandom"; - ::arg().set("dont-query", "If set, do not query these netmasks for DNS data") = DONT_QUERY; - ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)") = "0"; - ::arg().set("max-tcp-queries-per-connection", "If set, maximum number of TCP queries in a TCP connection") = "0"; - ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses") = "1"; - ::arg().setSwitch("single-socket", "If set, only use a single socket for outgoing queries") = "off"; - ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ") = ""; - ::arg().set("lua-config-file", "More powerful configuration options") = ""; - ::arg().setSwitch("allow-trust-anchor-query", "Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT") = "no"; - - ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs") = ""; - ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs") = ""; - ::arg().set("forward-zones-file", "File with (+)domain=ip pairs for forwarding") = ""; - ::arg().setSwitch("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off"; - ::arg().set("export-etc-hosts-search-suffix", "Also serve up the contents of /etc/hosts with this suffix") = ""; - ::arg().set("etc-hosts-file", "Path to 'hosts' file") = "/etc/hosts"; - ::arg().setSwitch("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes"; - ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers") = ""; - ::arg().set("lua-maintenance-interval", "Number of seconds between calls to the lua user defined maintenance() function") = "1"; - ::arg().set("latency-statistic-size", "Number of latency values to calculate the qa-latency average") = "10000"; - ::arg().setSwitch("disable-packetcache", "Disable packetcache") = "no"; - ::arg().set("ecs-ipv4-bits", "Number of bits of IPv4 address to pass for EDNS Client Subnet") = "24"; - ::arg().set("ecs-ipv4-cache-bits", "Maximum number of bits of IPv4 mask to cache ECS response") = "24"; - ::arg().set("ecs-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet") = "56"; - ::arg().set("ecs-ipv6-cache-bits", "Maximum number of bits of IPv6 mask to cache ECS response") = "56"; - ::arg().setSwitch("ecs-ipv4-never-cache", "If we should never cache IPv4 ECS responses") = "no"; - ::arg().setSwitch("ecs-ipv6-never-cache", "If we should never cache IPv6 ECS responses") = "no"; - ::arg().set("ecs-minimum-ttl-override", "The minimum TTL for records in ECS-specific answers") = "1"; - ::arg().set("ecs-cache-limit-ttl", "Minimum TTL to cache ECS response") = "0"; - ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for (deprecated)") = ""; - ::arg().set("edns-subnet-allow-list", "List of netmasks and domains that we should enable EDNS subnet for") = ""; - ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE; - ::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = ""; - ::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no"; - ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no"; - ::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes"; - ::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no"; - ::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no"; - ::arg().setSwitch("gettag-needs-edns-options", "If EDNS Options should be extracted before calling the gettag() hook") = "no"; - ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate") = "1232"; - ::arg().set("edns-outgoing-bufsize", "Outgoing EDNS buffer size") = "1232"; - ::arg().set("minimum-ttl-override", "The minimum TTL") = "1"; - ::arg().set("max-qperq", "Maximum outgoing queries per query") = "60"; - ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13"; - ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10"; - ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000"; - ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "16"; - ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing") = "10000"; - ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)") = ""; - ::arg().set("distribution-pipe-buffer-size", "Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread") = "0"; - - ::arg().set("include-dir", "Include *.conf files from this directory") = ""; - ::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com."; - -#ifdef SO_REUSEPORT - ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes"; -#else - ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no"; -#endif - ::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no"; - ::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = ""; - ::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = ""; - - std::string defaultAPIDisabledStats = "cache-bytes, packetcache-bytes, special-memory-usage"; - for (size_t idx = 0; idx < 32; idx++) { - defaultAPIDisabledStats += ", ecs-v4-response-bits-" + std::to_string(idx + 1); - } - for (size_t idx = 0; idx < 128; idx++) { - defaultAPIDisabledStats += ", ecs-v6-response-bits-" + std::to_string(idx + 1); - } - std::string defaultDisabledStats = defaultAPIDisabledStats + ", cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count"; - - ::arg().set("stats-api-blacklist", "List of statistics that are disabled when retrieving the complete list of statistics via the API (deprecated)") = defaultAPIDisabledStats; - ::arg().set("stats-carbon-blacklist", "List of statistics that are prevented from being exported via Carbon (deprecated)") = defaultDisabledStats; - ::arg().set("stats-rec-control-blacklist", "List of statistics that are prevented from being exported via rec_control get-all (deprecated)") = defaultDisabledStats; - ::arg().set("stats-snmp-blacklist", "List of statistics that are prevented from being exported via SNMP (deprecated)") = defaultDisabledStats; - - ::arg().set("stats-api-disabled-list", "List of statistics that are disabled when retrieving the complete list of statistics via the API") = defaultAPIDisabledStats; - ::arg().set("stats-carbon-disabled-list", "List of statistics that are prevented from being exported via Carbon") = defaultDisabledStats; - ::arg().set("stats-rec-control-disabled-list", "List of statistics that are prevented from being exported via rec_control get-all") = defaultDisabledStats; - ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP") = defaultDisabledStats; - - ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size") = "0"; - ::arg().setSwitch("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no"; - ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record") = "150"; - - ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs") = ""; - - ::arg().setSwitch("log-rpz-changes", "Log additions and removals to RPZ zones at Info level") = "no"; - - ::arg().set("proxy-protocol-from", "A Proxy Protocol header is only allowed from these subnets") = ""; - ::arg().set("proxy-protocol-maximum-size", "The maximum size of a proxy protocol payload, including the TLV values") = "512"; - - ::arg().set("dns64-prefix", "DNS64 prefix") = ""; - - ::arg().set("udp-source-port-min", "Minimum UDP port to bind on") = "1024"; - ::arg().set("udp-source-port-max", "Maximum UDP port to bind on") = "65535"; - ::arg().set("udp-source-port-avoid", "List of comma separated UDP port number to avoid") = "11211"; - ::arg().set("rng", "Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.") = "auto"; - ::arg().set("public-suffix-list-file", "Path to the Public Suffix List file, if any") = ""; - ::arg().set("distribution-load-factor", "The load factor used when PowerDNS is distributing queries to worker threads") = "0.0"; - - ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes"; - ::arg().set("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; - ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0"; - ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20"; - - ::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024"; - ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024"; - - ::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0"; - ::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0"; - - ::arg().set("x-dnssec-names", "Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters") = ""; - -#ifdef NOD_ENABLED - ::arg().setSwitch("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no"; - ::arg().setSwitch("new-domain-log", "Log newly observed domains.") = "yes"; - ::arg().set("new-domain-lookup", "Perform a DNS lookup newly observed domains as a subdomain of the configured domain") = ""; - ::arg().set("new-domain-history-dir", "Persist new domain tracking data here to persist between restarts") = string(NODCACHEDIR) + "/nod"; - ::arg().set("new-domain-whitelist", "List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)") = ""; - ::arg().set("new-domain-ignore-list", "List of domains (and implicitly all subdomains) which will never be considered a new domain") = ""; - ::arg().set("new-domain-db-size", "Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864") = "67108864"; - ::arg().set("new-domain-pb-tag", "If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to 'pdns-nod'") = "pdns-nod"; - ::arg().setSwitch("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no"; - ::arg().setSwitch("unique-response-log", "Log unique responses") = "yes"; - ::arg().set("unique-response-history-dir", "Persist unique response tracking data here to persist between restarts") = string(NODCACHEDIR) + "/udr"; - ::arg().set("unique-response-db-size", "Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864") = "67108864"; - ::arg().set("unique-response-pb-tag", "If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to 'pdns-udr'") = "pdns-udr"; -#endif /* NOD_ENABLED */ - - ::arg().setSwitch("extended-resolution-errors", "If set, send an EDNS Extended Error extension on resolution failures, like DNSSEC validation errors") = "no"; - - ::arg().set("aggressive-nsec-cache-size", "The number of records to cache in the aggressive cache. If set to a value greater than 0, and DNSSEC processing or validation is enabled, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in rfc8198") = "100000"; - ::arg().set("aggressive-cache-min-nsec3-hit-ratio", "The minimum expected hit ratio to store NSEC3 records into the aggressive cache") = "2000"; - - ::arg().set("edns-padding-from", "List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that 'edns-padding-mode' applies") = ""; - ::arg().set("edns-padding-mode", "Whether to add EDNS padding to all responses ('always') or only to responses for queries containing the EDNS padding option ('padded-queries-only', the default). In both modes, padding will only be added to responses for queries coming from `edns-padding-from`_ sources") = "padded-queries-only"; - ::arg().set("edns-padding-tag", "Packetcache tag associated to responses sent with EDNS padding, to prevent sending these to clients for which padding is not enabled.") = "7830"; - ::arg().setSwitch("edns-padding-out", "Whether to add EDNS padding to outgoing DoT messages") = "yes"; - - ::arg().setSwitch("dot-to-port-853", "Force DoT connection to target port 853 if DoT compiled in") = "yes"; - ::arg().set("dot-to-auth-names", "Use DoT to authoritative servers with these names or suffixes") = ""; - ::arg().set("event-trace-enabled", "If set, event traces are collected and send out via protobuf logging (1), logfile (2) or both(3)") = "0"; - - ::arg().set("tcp-out-max-idle-ms", "Time TCP/DoT connections are left idle in milliseconds or 0 if no limit") = "10000"; - ::arg().set("tcp-out-max-idle-per-auth", "Maximum number of idle TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open") = "10"; - ::arg().set("tcp-out-max-queries", "Maximum total number of queries per TCP/DoT connection, 0 means no limit") = "0"; - ::arg().set("tcp-out-max-idle-per-thread", "Maximum number of idle TCP/DoT connections per thread") = "100"; - ::arg().setSwitch("structured-logging", "Prefer structured logging") = "yes"; - ::arg().set("structured-logging-backend", "Structured logging backend") = "default"; - ::arg().setSwitch("save-parent-ns-set", "Save parent NS set to be used if child NS set fails") = "yes"; - ::arg().set("max-busy-dot-probes", "Maximum number of concurrent DoT probes") = "0"; - ::arg().set("serve-stale-extensions", "Number of times a record's ttl is extended by 30s to be served stale") = "0"; - - ::arg().setCmd("help", "Provide a helpful message"); - ::arg().setCmd("version", "Print version string"); - ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments."); - ::arg().setDefaults(); - g_log.toConsole(Logger::Info); - - if (s_generateConfigTable) { - auto file = ofstream("settings/table.py"); - const std::map overrideMap = { - {"allow-from", "LType.ListSubnets"}, - {"allow-notify-for", "LType.ListStrings"}, - {"allow-notify-from", "LType.ListSubnets"}, - {"auth-zones", "LType.ListStrings"}, - {"dnssec-disabled-algorithms", "LType.ListStrings"}, - {"dont-query", "LType.ListSubnets"}, - {"dont-throttle-names", "LType.ListStrings"}, - {"dont-throttle-netmasks", "LType.ListSubnets"}, - {"dot-to-auth-names", "LType.ListStrings"}, - {"ecs-add-for", "LType.ListSubnets"}, - {"edbs-padding-from", "LType.ListSubnets"}, - {"edns-subnet-allow-list", "LType.ListSubnets"}, - {"forwad-zones", "LType.ListStrings"}, - {"forwad-zones-recurse", "LType.Strings"}, - {"local-address", "LType.ListSocketAddresses"}, - {"new-domain-ignore-list", "LType.ListStrings"}, - {"query-local-address", "LType.ListSubnets"}, - {"stats-api-disabled-list", "LType.ListStrings"}, - {"stats-carbon-disabled-list", "LType.ListStrings"}, - {"stats-rec-control-disabled-list", "LType.ListStrings"}, - {"stats-snmp-disabled-list", "LType.ListStrings"}, - {"webserver-allow-from", "LType.ListSubnets"}, - {"x-dnssec-names", "LType.ListStrings"}, - }; - file << ::arg().table(overrideMap); - file.close(); - } -} -#endif - static pair doYamlConfig(Logr::log_t /* startupLog */, int argc, char* argv[]) // NOLINT: Posix API { if (!::arg().mustDo("config")) { diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index daeb0dc77f..9fc1d96bc8 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -211,6 +211,7 @@ extern uint16_t g_udpTruncationThreshold; extern double g_balancingFactor; extern size_t g_maxUDPQueriesPerRound; extern bool g_useKernelTimestamp; +extern bool g_allowNoRD; extern thread_local std::shared_ptr t_allowFrom; extern thread_local std::shared_ptr t_allowNotifyFrom; extern thread_local std::shared_ptr t_allowNotifyFor; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index a4778bdb08..5086ec7609 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -194,6 +194,18 @@ Like :ref:`setting-allow-notify-from`, except reading a sequence of `Subnet`_ fr ''', 'versionadded': '4.6.0' }, + { + 'name' : 'allow_no_rd', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Allow \'no recursion desired (RD=0)\' queries.', + 'doc' : ''' +Allow ``no recursion desired (RD=0) queries`` to query cache contents. +If not set (the default), these queries are answered with rcode ``Refused``. + ''', + 'versionadded': '5.5.0' + }, { 'name' : 'any_to_tcp', 'section' : 'recursor', @@ -204,7 +216,7 @@ Like :ref:`setting-allow-notify-from`, except reading a sequence of `Subnet`_ fr Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. Useful for mitigating ANY reflection attacks. ''', - }, + }, { 'name' : 'allow_trust_anchor_query', 'section' : 'recursor',