blog.robur.coop

The Robur cooperative blog.
Back to index

DNSvizor Gets Blocklists

2025-06-25

TL;DR: DNSvizor now has support for DNS blocklists. We are continuing our work on DNSvizor (repository).

Blocking DNS queries

DNSvizor has a built-in recursive resolver that clients on the network can query. That is, a client on the network might want to visit a website. This requires the client connects to a machine usually through a domain name (e.g. www.example.com). The client queries the local recursive resolver for what IP address corresponds to the domain name (www.example.com). Once connected the web page may kick off more requests for things such as images, JavaScript code, advertisement, tracking pixels and other resources. These other resources may live on the same domain or they may live on another domain (e.g. cdn.example.com, ads.example.com, track.example.com, malware.example.net).

As you may have guessed not all of these resources are desirable. Lucky for us it's often the case that these undesirable resources are served from dedicated domains - meaning we can block the domains and not lose access to resources of interest. There are curated lists of domains to block. This summer we have been working hard on adding support for blocking domains via block lists and manual blocks, and it's our pleasure to announce that it is now available! For transparency to the clients on the network a special error code is added to the response to communicate that the response has been blocked - blocking is after all a two edged sword and can be used to censor legitimate hosts or break legitimate network applications.

Changes required

The changes made in DNSvizor are available in this PR on GitHub. It works by adding special DNS SOA records to the internal DNS primary server in DNSvizor. It required a number of changes in our DNS library:

Design

The recursive DNS resolver comes with a built-in DNS primary server. This may sound a bit confusing, but this is so the recursive resolver can be set up to have local (internal) domains. We use this internal DNS primary server to claim blocked domains and serve NXDOMAIN (nonexistent domain) in response. This is done by inserting a [SOA][https://en.wikipedia.org/wiki/SOA_record] record for that domain. In order to let the resolver know we claim it because we want to block the domain we use the special blocked domain name for the SOA primary DNS server field. We also embed the source of the block in the hostmaster field of the SOA record. This way we can inform the client that the domain was blocked, and we can iterate over the DNS trie to collect numbers to display in the web interface how many domains are blocked through each source (block list). Finally, we keep a serial for each block list so on each update we can see if there are domains that no longer need to be blocked by checking the serial.

Blocklists

The format of a block list can take various forms. The format we support is (mostly) the same as the format for /etc/hosts on UNIX(-like) systems. That is, an IP address followed by tabs or spaces (whitespace) and a whitespace separated list of domains. The IP address is usually 0.0.0.0 or ::. Line comments start with a # and are silently ignored. We also support lines without an IP address in front - a format we have found in the wild.

These block lists can be quite long. For example, the default list in pi-hole (https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts) is 6.1 MBs of plain text! For unikernels which are often memory constrained this is rather a lot of data to process! In order to keep memory usage low we process the block lists in a streaming fashion (re)building the DNS trie as data comes in. This means we only have to buffer as much as to be able to read a line at a time. Still, we have an issue with memory consumption as the internal DNS primary server keeps a backlog of SOAs with older serials in order to better compute incremental transfers to secondaries - something we don't support in the resolver setup. We will address this and other issues in the following days in our performance improvement milestone for our NLnet funded project.

Conclusion

DNSvizor provides DNS resolution and DHCP service for your network with a web interface - now with blocklist support. It already exists :). Please report issues you encounter and questions you may have. Also, if you use dnsmasq, please show us your configuration.

If you're interested in MirageOS and using it in your domain, don't hesitate to reach out to us (via eMail: team@robur.coop) - we're keen to deploy MirageOS and find more domains where it is useful.

Our work is only partially funded, we cross-fund our work by commercial contracts and public (EU) funding. We are part of a non-profit company, you can make a (in the EU tax-deductible) donation (select "DONATION robur" in the dropdown menu), or sponsor us via the GitHub sponsor button.