<div dir="ltr"><div>I'm seeing an issue where caching resolvers outside of our network are occasionally storing empty responses to queries.<br></div><div><br></div><div>I think what's happening is that when a query is made and there's a backend timeout, dnsdist is responding to the user with an empty answer and NOERROR. Messages about a backend beign marked as down are in the log coinciding with when this has happened.<br></div><div><br></div><div>I've not caught dnsdist in the act yet with a packet capture as the issue is infrequent, but am I on the right track?</div><div><br></div><div>Is it possible to make dnsdist respond with a SERVFAIL for a backend timeout?</div><div><br></div><div>Many Thanks,</div><div>Adam</div><div><br></div><div>---</div><div><br></div><div>--<br>-- UI<br>--<br><br>-- Enable the CLI<br>setKey("")<br>controlSocket("<a href="http://127.0.0.1:5199">127.0.0.1:5199</a>")<br>controlSocket("[::1]:5199")<br><br>-- Enable stats monitoring and graphing via HTTP<br>webserver("<a href="http://127.0.0.1:8080">127.0.0.1:8080</a>")<br>webserver("[::1]:8080")<br>setWebserverConfig(<br>    {<br>        customHeaders = {["X-Served-By"] = ""},<br>        apiKey = "",<br>        password = ""<br>    }<br>)<br><br>--<br>-- Services<br>--<br><br>-- Listen on port 53 for IPv4 and IPv6 with TCP and UDP<br>addLocal("<a href="http://0.0.0.0:53">0.0.0.0:53</a>", {reusePort = true, maxInFlight = 65535})<br>addLocal("[::]:53", {reusePort = true, maxInFlight = 65535})<br><br>setACL({'<a href="http://0.0.0.0/0">0.0.0.0/0</a>', '::/0'})<br><br>setECSSourcePrefixV4(32)<br>setECSSourcePrefixV6(128)<br><br>authdomains = newSuffixMatchNode()<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br>authdomains:add(newDNSName(""))<br><br>--<br>-- Backends<br>--<br><br>setVerboseHealthChecks(true)<br><br>newServer(<br>    {<br>        address = "",<br>        order = 3,<br>        useClientSubnet = true,<br>        checkType = "SOA",<br>        checkName = "",<br>        mustResolve = true,<br>        tcpFastOpen = true,<br>        checkTCP = true,<br>        tcpOnly = true,<br>        maxInFlight = 65535,<br>        reconnectOnUp = true,<br>        checkInterval = 30<br>    }<br>)<br><br>newServer(<br>    {<br>        address = "",<br>        order = 4,<br>        useClientSubnet = true,<br>        checkType = "SOA",<br>        checkName = "",<br>        mustResolve = true,<br>        tcpFastOpen = true,<br>        checkTCP = true,<br>        tcpOnly = true,<br>        maxInFlight = 65535,<br>        reconnectOnUp = true,<br>        checkInterval = 30<br>    }<br>)<br><br>newServer(<br>    {<br>        address = "",<br>        order = 1,<br>        useClientSubnet = true,<br>        checkType = "SOA",<br>        checkName = "",<br>        mustResolve = true,<br>        tcpFastOpen = true,<br>        checkTCP = true,<br>        tcpOnly = true,<br>        maxInFlight = 65535,<br>        reconnectOnUp = true,<br>        checkInterval = 30<br>    }<br>)<br><br>newServer(<br>    {<br>        address = "",<br>        order = 2,<br>        useClientSubnet = true,<br>        checkType = "SOA",<br>        checkName = "",<br>        mustResolve = true,<br>        tcpFastOpen = true,<br>        checkTCP = true,<br>        tcpOnly = true,<br>        maxInFlight = 65535,<br>        reconnectOnUp = true,<br>        checkInterval = 30<br>    }<br>)<br><br>setServerPolicy(firstAvailable)<br>getPool(""):setECS(true)<br><br>--<br>-- Caching<br>--<br><br>-- Attach a cache to the default pool to store records up to 1 week<br>getPool(""):setCache(<br>    newPacketCache(<br>        1000000,<br>        {<br>            maxTTL = 604800,<br>            minTTL = 0,<br>            temporaryFailureTTL = 30,<br>            staleTTL = 30,<br>            dontAge = true,<br>            keepStaleData = true,<br>            parseECS = true,<br>            cookieHashing = true<br>        }<br>    )<br>)<br><br>-- rfc8767 recommends a stale lifetime of 1 to 3 days<br>setStaleCacheEntriesTTL(259200)<br><br>--<br>-- Tuning<br>--<br><br>-- Increase the in-memory rings size (the default, 10000, is only one second at 10k qps) used by<br>-- live-traffic inspection features like grepq, and use 100 shards to improve performance<br>setRingBuffersSize(1000000, 100)<br><br>-- increase the number of TCP workers, each one being capable of handling a large number<br>-- of TCP connections since 1.4.0<br>setMaxTCPClientThreads(8)<br><br>--<br>-- DNS Rules (Ingress)<br>--<br><br>-- Special: Log the packet to syslog<br>addAction(AllRule(), LogAction("", false, false, false, false))<br><br>-- Special: Strip the rd bit from all traffic<br>addAction(RDRule(), SetNoRecurseAction())<br><br>-- Special: Reply to ANY queries with NOTIMP<br>addAction(QTypeRule(DNSQType.ANY), ERCodeAction(DNSRCode.NOTIMP, {ra = false}))<br><br>-- Filter: Allow only 'good' queries to specified domains<br>addAction(<br>    AndRule(<br>        {<br>            -- Allow only queries to specified domains<br>            SuffixMatchNodeRule(authdomains),<br>            -- Allow only regular queries<br>            NotRule(<br>                OrRule(<br>                    {<br>                        QTypeRule(DNSQType.AXFR),<br>                        QTypeRule(DNSQType.IXFR)<br>                    }<br>                )<br>            ),<br>            -- Allow only regular opcodes<br>            NotRule(<br>                OrRule(<br>                    {<br>                        OpcodeRule(DNSOpcode.Notify),<br>                        OpcodeRule(DNSOpcode.Update),<br>                        OpcodeRule(DNSOpcode.IQuery),<br>                        OpcodeRule(DNSOpcode.Status)<br>                    }<br>                )<br>            ),<br>            -- Allow only 'IN',<br>            QClassRule(1)<br>        }<br>    ),<br>    AllowAction()<br>)<br><br>-- Default deny: refuse everthing else<br>addAction(AllRule(), RCodeAction(DNSRCode.REFUSED, {ra = false}))<br><br>--<br>-- DNS Rules (Egress)<br>--<br><br>-- Special: Log the response to syslog<br>addResponseAction(AllRule(), LogResponseAction("", false, false, false, false))</div></div>