The CoreDNS ads plugin is a surprisingly effective way to stop tracking and ads at the DNS level, but most people think of it as just a simple blocklist filter when its real power lies in its ability to dynamically block entire domains based on their behavior.

Let’s see it in action. Imagine you’re browsing a site, and you notice ads popping up. You’ve got CoreDNS running with the ads plugin enabled.

Here’s a snippet of a CoreDNS configuration:

.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    # The magic line:
    ads {
        # Point to your blocklist files
        blocklist /etc/coredns/blocklist.txt
        # You can specify multiple lists
        blocklist /etc/coredns/easylist.txt
        # Enable dynamic blocking
        dynamic on
        # Set the TTL for blocked domains
        ttl 300
    }
    cache 30
    loop
    reload
    loadbalance
}

When your browser requests ads.example.com (a hypothetical ad server), CoreDNS intercepts it. If ads.example.com is in your blocklist.txt or easylist.txt, CoreDNS will return an NXDOMAIN (non-existent domain) response. If dynamic on is set, and CoreDNS sees a pattern of requests to domains that are known to serve ads or track users, it can start blocking them even if they aren’t explicitly listed, based on heuristics and learned patterns. The ttl 300 means that even if a domain is temporarily blocked dynamically, that block will expire after 300 seconds (5 minutes), allowing for more flexibility.

The core problem this solves is the constant barrage of unsolicited requests to third-party domains that drain bandwidth, compromise privacy, and slow down your browsing experience. By handling this at the DNS layer, you prevent the requests from even leaving your network, making your internet usage cleaner and faster.

Internally, the ads plugin works by maintaining an in-memory set of blocked domains. When a DNS query arrives, it’s first checked against this set. If a match is found, the query is immediately dropped or resolved to a null IP. The blocklist directive tells CoreDNS where to load its initial set of blocked domains from. These files are typically plain text files, with one domain per line, like:

ads.example.com
tracker.anothersite.net
doubleclick.net

The dynamic on directive is where the real intelligence comes in. CoreDNS, through this plugin, can observe DNS traffic. If it notices a high volume of requests to a particular domain, especially from multiple clients, and that domain isn’t in the explicit blocklist, it can infer that this domain is likely involved in advertising or tracking. It then adds this domain to its internal blocklist for a specified duration (controlled by ttl). This means your blocklist grows organically as you browse, catching new or evolving tracking domains.

The ttl parameter is crucial for dynamic blocking. A shorter TTL means dynamically blocked domains will be unblocked more frequently, which can be useful if a domain is sometimes legitimate and sometimes used for tracking. A longer TTL provides more persistent blocking.

What many people miss is that the ads plugin doesn’t just blindly trust external lists. When dynamic on is enabled, it starts to build its own understanding of your network’s traffic patterns to identify potential blockers. This is less about a static blacklist and more about a dynamic, context-aware filtering mechanism that adapts to your actual internet usage. It’s like having a spam filter that learns not just from known spam senders, but also from the characteristics of emails you consistently mark as spam.

The next step after implementing this is often exploring how to integrate custom blocklists from various privacy-focused communities or even setting up your own dynamic rules based on specific services you use.

Want structured learning?

Take the full Coredns course →