[dnsdist] Empty NOERROR being sent when backend times out

Adam Bishop adam at omega.org.uk
Fri Feb 9 10:05:00 UTC 2024


I'm seeing an issue where caching resolvers outside of our network are
occasionally storing empty responses to queries.

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.

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?

Is it possible to make dnsdist respond with a SERVFAIL for a backend
timeout?

Many Thanks,
Adam

---

--
-- UI
--

-- Enable the CLI
setKey("")
controlSocket("127.0.0.1:5199")
controlSocket("[::1]:5199")

-- Enable stats monitoring and graphing via HTTP
webserver("127.0.0.1:8080")
webserver("[::1]:8080")
setWebserverConfig(
    {
        customHeaders = {["X-Served-By"] = ""},
        apiKey = "",
        password = ""
    }
)

--
-- Services
--

-- Listen on port 53 for IPv4 and IPv6 with TCP and UDP
addLocal("0.0.0.0:53", {reusePort = true, maxInFlight = 65535})
addLocal("[::]:53", {reusePort = true, maxInFlight = 65535})

setACL({'0.0.0.0/0', '::/0'})

setECSSourcePrefixV4(32)
setECSSourcePrefixV6(128)

authdomains = newSuffixMatchNode()
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))
authdomains:add(newDNSName(""))

--
-- Backends
--

setVerboseHealthChecks(true)

newServer(
    {
        address = "",
        order = 3,
        useClientSubnet = true,
        checkType = "SOA",
        checkName = "",
        mustResolve = true,
        tcpFastOpen = true,
        checkTCP = true,
        tcpOnly = true,
        maxInFlight = 65535,
        reconnectOnUp = true,
        checkInterval = 30
    }
)

newServer(
    {
        address = "",
        order = 4,
        useClientSubnet = true,
        checkType = "SOA",
        checkName = "",
        mustResolve = true,
        tcpFastOpen = true,
        checkTCP = true,
        tcpOnly = true,
        maxInFlight = 65535,
        reconnectOnUp = true,
        checkInterval = 30
    }
)

newServer(
    {
        address = "",
        order = 1,
        useClientSubnet = true,
        checkType = "SOA",
        checkName = "",
        mustResolve = true,
        tcpFastOpen = true,
        checkTCP = true,
        tcpOnly = true,
        maxInFlight = 65535,
        reconnectOnUp = true,
        checkInterval = 30
    }
)

newServer(
    {
        address = "",
        order = 2,
        useClientSubnet = true,
        checkType = "SOA",
        checkName = "",
        mustResolve = true,
        tcpFastOpen = true,
        checkTCP = true,
        tcpOnly = true,
        maxInFlight = 65535,
        reconnectOnUp = true,
        checkInterval = 30
    }
)

setServerPolicy(firstAvailable)
getPool(""):setECS(true)

--
-- Caching
--

-- Attach a cache to the default pool to store records up to 1 week
getPool(""):setCache(
    newPacketCache(
        1000000,
        {
            maxTTL = 604800,
            minTTL = 0,
            temporaryFailureTTL = 30,
            staleTTL = 30,
            dontAge = true,
            keepStaleData = true,
            parseECS = true,
            cookieHashing = true
        }
    )
)

-- rfc8767 recommends a stale lifetime of 1 to 3 days
setStaleCacheEntriesTTL(259200)

--
-- Tuning
--

-- Increase the in-memory rings size (the default, 10000, is only one
second at 10k qps) used by
-- live-traffic inspection features like grepq, and use 100 shards to
improve performance
setRingBuffersSize(1000000, 100)

-- increase the number of TCP workers, each one being capable of handling a
large number
-- of TCP connections since 1.4.0
setMaxTCPClientThreads(8)

--
-- DNS Rules (Ingress)
--

-- Special: Log the packet to syslog
addAction(AllRule(), LogAction("", false, false, false, false))

-- Special: Strip the rd bit from all traffic
addAction(RDRule(), SetNoRecurseAction())

-- Special: Reply to ANY queries with NOTIMP
addAction(QTypeRule(DNSQType.ANY), ERCodeAction(DNSRCode.NOTIMP, {ra =
false}))

-- Filter: Allow only 'good' queries to specified domains
addAction(
    AndRule(
        {
            -- Allow only queries to specified domains
            SuffixMatchNodeRule(authdomains),
            -- Allow only regular queries
            NotRule(
                OrRule(
                    {
                        QTypeRule(DNSQType.AXFR),
                        QTypeRule(DNSQType.IXFR)
                    }
                )
            ),
            -- Allow only regular opcodes
            NotRule(
                OrRule(
                    {
                        OpcodeRule(DNSOpcode.Notify),
                        OpcodeRule(DNSOpcode.Update),
                        OpcodeRule(DNSOpcode.IQuery),
                        OpcodeRule(DNSOpcode.Status)
                    }
                )
            ),
            -- Allow only 'IN',
            QClassRule(1)
        }
    ),
    AllowAction()
)

-- Default deny: refuse everthing else
addAction(AllRule(), RCodeAction(DNSRCode.REFUSED, {ra = false}))

--
-- DNS Rules (Egress)
--

-- Special: Log the response to syslog
addResponseAction(AllRule(), LogResponseAction("", false, false, false,
false))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.powerdns.com/pipermail/dnsdist/attachments/20240209/a493bf0d/attachment.htm>


More information about the dnsdist mailing list