Using dnsdist

Below is a simple configuration for setting up dnsdist as a server offering both DoT and DoH

addACL('0.0.0.0/0')
addACL('::/0')

addLocal('0.0.0.0:53',{doTCP=true, reusePort=true, tcpFastOpenSize=X})        -- for dns over port 53 ipv4 , set X(int) for tcp fast open queue size
addLocal('[::]:53',   {doTCP=true, reusePort=true, tcpFastOpenSize=X})        -- for dns over port 53 ipv6 , set X(int) for tcp fast open queue size

addTLSLocal("0.0.0.0", "/Path/fullchain.pem", "/Path/privkey.pem",{ doTCP=true, reusePort=true, tcpFastOpenSize=X })      
-- path for certs and listen address for DoT ipv4 , by default listens on port 853. Set X(int) for tcp fast open queue size.
addTLSLocal("[::]", "/Path/fullchain.pem", "/Path/privkey.pem",{ doTCP=true, reusePort=true, tcpFastOpenSize=X })         
-- path for certs and listen address for DoT ipv6 , by default listens on port 853. Set X(int) for tcp fast open queue size.

addDOHLocal("[::]:443", "/Path/fullchain.pem", "/Path/privkey.pem", "/dns-query", { doTCP=true, reusePort=true, tcpFastOpenSize=X })        
-- path for certs and listen address for DoH. Set X(int) for tcp fast open queue size.

addAction(MaxQPSIPRule(X), DropAction())    -- set X(int) number of queries to be allowed per second from a IP
addAction(AndRule({QTypeRule(dnsdist.ANY), TCPRule(false)}), DropAction())  -- drop ANY queries sent over udp , not useful for DoT and DoH only servers.

pc = newPacketCache(X, 86400, 600)      -- set X number of entries to be in dnsdist cache by default , memory will be preallocated based on the X number
getPool(""):setCache(pc)              -- deafult cache
setServerPolicy(leastOutstanding)       -- server policy to choose the downstream servers for recursion

newServer({address="127.0.0.1:1111", name="resolver1"})     -- downstream servers for recursion
newServer({address="127.0.0.1:2222", name="resolver2"})     -- downstream servers for recursion

setMaxUDPOutstanding(65535)
setMaxTCPClientThreads(X)           -- set X(int) to handle number of maximum tcp clients
setMaxTCPConnectionDuration(X)      -- set X(int) for tcp connection duaration from a connected client. X is number of seconds.
setMaxTCPConnectionsPerClient(X)    -- set X(int) for number of tcp connections from a single client. Useful for rate limiting the concurrent connections.
setMaxTCPQueriesPerConnection(X)    -- set X(int) , similiar to addAction(MaxQPSIPRule(X), DropAction())