Most heavy lifting is done by Nginx and CoreDNS.

We use Nginx to terminate all TLS and forward everything downstream to coredns for filtering and ultimately forwarded to a local recursive resolver.

One of the main benefits of using CoreDNS as the filtering DNS is it’s proven stability and responce performance as the go-to DNS service for Kubernetes. It can easily be enhanced with own modules and has a minimal resource footprint as well as seamless reloads of any and all configuration files, including the filter-list.

We opted for Knot Resolver for our local resolver as they provide a significant performance gain over BIND/Named and other common recursive resolvers. Specially the multi-core pinning and listener sharing allows it for uninterrupted upgrades.

Access

  • DNS-over-HTTPS: https://resolver.r0cket.net/dns-query
  • DNS-over-TLS: tls://resolver.r0cket.net:853
  • DNS (udp and tcp): 185.243.23.151:53

Configuration Files

filter sources:

https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
https://adaway.org/hosts.txt
https://hosts-file.net/ad_servers.txt
https://mirror1.malwaredomains.com/files/justdomains
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
http://sysctl.org/cameleon/hosts

knot-resolver/kresd.conf:

net.listen('127.0.0.1', 10053, { kind = 'dns', freebind = true })

-- Required for prometheus exporter:
net.listen('127.0.0.1', 18453, { kind = 'webmgmt', freebind = true })

-- Load useful modules
modules = {
        'hints > iterate',  -- Load /etc/hosts and allow custom root hints
        'stats',            -- Track internal statistics
        'predict',          -- Prefetch expiring/frequent records
        'http',             -- Also required for prometheus
}
cache.size = 100 * MB
http.config({ tls = false, })
http.prometheus.namespace = 'kresd_'

CoreDNS/Corefile:

. {
        reload
        bind 0.0.0.0

        # Catch .lan queries to not spend pointless compute.
        # Could be expanded to .local as well
        template ANY ANY lan {
                rcode NXDOMAIN
                fallthrough
        }

        # Use the filter-list to remove ads and trackers
        hosts /ban.list {
                no_reverse
                reload 60s
                fallthrough
        }

        # Forward all non-filtered requests to the local knot-resolver
        # or known fallback hosts.
        forward . 127.0.0.1:10053 1.1.1.1 8.8.8.8 8.8.4.4 {
                except lan
                policy sequential
                health_check 0.5s
                prefer_udp
        }

        cache
        prometheus 127.0.0.1:9153
        errors
}