DNS-level adblock on the go with blocky

2024-05-31

Introduction#

An adblocker is something you commonly find installed in browsers, usually through an extension. However, what if you wanted an adblocking system that was a bit deeper? Something that doesn't require a browser extension, and gives you a consistent adblocking system? This is where DNS-level adblockers like AdGuard Home or Pi-hole come in.

DNS?#

DNS stands for Domain Name System. It's what points URLs like https://duck.com to an IP address (like 52.142.124.215), making it much easier to find things on the internet.

DNS-level adblockers work by filtering out queries for URLs pointing to IP addresses serving ads. In this blog post, I'll use blocky as an example of one such adblocker for demonstration purposes.

Setting up blocky#

NixOS configuration#

There's a configuration option for blocky provided by NixOS, so you can enable and configure it in your NixOS config:

1services.blocky = {
2 enable = true;
3 settings = {
4 prometheus.enable = true;
5 blocking = {
6 blackLists.ads = [
7 "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
8 "https://sysctl.org/cameleon/hosts"
9 "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt"
10 "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt"
11 ];
12 clientGroupsBlock = {
13 default = [ "ads" ];
14 };
15 };
16 upstreams = {
17 groups.default = [
18 "9.9.9.9"
19 "1.1.1.1"
20 ];
21 };
22 ports = {
23 dns = "0.0.0.0:53";
24 };
25 };
26};

Why isn't it running?

You might need to reboot after running a nixos-rebuild switch, or move/kill any process running on port 53 for this to work.

Custom DNS mapping

You can use blocky to map a domain of your choice to an IP of your choice - refer to the documentation for more information.

Here, I've used two upstream nameservers for blocky to forward valid DNS requests to (since blocky doesn't do any DNS resolution itself - except for custom mapping, detailed later). One is Cloudflare's DNS (1.1.1.1) and the other is Quad9 (9.9.9.9).

As indicated by lines 6 through 11, you need to add lists containing URLs you want to be filtered from your DNS requests.

Making it work everywhere#

The thing is, you'll need to set the IP address of the machine running blocky as a nameserver for all of your workstations - it just won't recieve any requests otherwise, so it won't be doing any adblocking if you don't do this.

Of course, if you've got a router worth keeping around, you should be able to set a network-wide DNS resolver, and you can point this to your blocky-running machine in your router's settings.

However, what if you wanted to have this work everywhere you go, perhaps on a portable laptop? Well, if you're using Tailscale or Headscale you can just can edit the nameservers you use in your VPN's settings and set it to the IP address of the device running blocky. This way, any device on your VPN can utilise blocky and have a functioning DNS-level adblocker no matter where you are.

If you're looking to setup headscale, I've made a blog post about it.

Finishing thoughts#

With the existence of browser extensions doing the same thing adblockers like blocky and Pi-hole can, not everyone is going to need something this sophisticated. I think something like this is better suited to those looking for better coverage in their adblocking, or something that gives more control over DNS requests - for example, to easily setup custom DNS mappings or to restrict access to certain websites.