nixpkgs/nixos/modules/services/networking/crab-hole.md
Peder Bergebakken Sundt d525eb5838 treewide: fix typos
done with `fd \\\.md$ . --type f -x typos --write-changes`
2025-02-22 02:02:07 +01:00

7.2 KiB

🦀 crab-hole

Crab-hole is a cross platform Pi-hole clone written in Rust using hickory-dns/trust-dns. It can be used as a network wide ad and spy blocker or run on your local PC.

For a secure and private communication, crab-hole has builtin support for DoH(HTTPS), DoQ(QUIC) and DoT(TLS) for down- and upstreams and DNSSEC for upstreams. It also comes with privacy friendly default logging settings.

Configuration

As an example config file using Cloudflare as DoT upstream, you can use this crab-hole.toml

The following is a basic nix config using UDP as a downstream and Cloudflare as upstream.

{
  services.crab-hole = {
    enable = true;

    settings = {
      blocklist = {
        include_subdomains = true;
        lists = [
          "https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn/hosts"
          "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt"
        ];
      };

      downstream = [
        {
          protocol = "udp";
          listen = "127.0.0.1";
          port = 53;
        }
        {
          protocol = "udp";
          listen = "::1";
          port = 53;
        }
      ];

      upstream = {
        name_servers = [
          {
            socket_addr = "1.1.1.1:853";
            protocol = "tls";
            tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
            trust_nx_responses = false;
          }
          {
            socket_addr = "[2606:4700:4700::1111]:853";
            protocol = "tls";
            tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
            trust_nx_responses = false;
          }
        ];
      };
    };
  };
}

To test your setup, just query the DNS server with any domain like example.com. To test if a domain gets blocked, just choose one of the domains from the blocklist. If the server does not return an IP, this worked correctly.

Downstream options

There are multiple protocols which are supported for the downstream: UDP, TLS, HTTPS and QUIC. Below you can find a brief overview over the various protocol options together with an example for each protocol.

UDP

UDP is the simplest downstream, but it is not encrypted. If you want encryption, you need to use another protocol. Note: This also opens a TCP port

{
  services.crab-hole.settings.downstream = [
    {
      protocol = "udp";
      listen = "localhost";
      port = 53;
    }
  ];
}

TLS

TLS is a simple encrypted options to serve DNS. It comes with similar settings to UDP, but you additionally need a valid TLS certificate and its private key. The later are specified via a path to the files. A valid TLS certificate and private key can be obtained using services like ACME. Make sure the crab-hole service user has access to these files. Additionally you can set an optional timeout value.

{
  services.crab-hole.settings.downstream = [
    {
      protocol = "tls";
      listen = "[::]";
      port = 853;
      certificate = ./dns.example.com.crt;
      key = "/dns.example.com.key";
      # optional (default = 3000)
      timeout_ms = 3000
    }
  ];
}

HTTPS

HTTPS has similar settings to TLS, with the only difference being the additional dns_hostname option. This protocol might need a reverse proxy if other HTTPS services are to share the same port. Make sure the service has permissions to access the certificate and key.

Note: this config is untested

{
  services.crab-hole.settings.downstream = [
    {
      protocol = "https";
      listen = "[::]";
      port = 443;
      certificate = ./dns.example.com.crt;
      key = "/dns.example.com.key";
      # optional
      dns_hostname = "dns.example.com";
      # optional (default = 3000)
      timeout_ms = 3000;
    }
  ];
}

QUIC

QUIC has identical settings to the HTTPS protocol. Since by default it doesn't run on the standard HTTPS port, you shouldn't need a reverse proxy. Make sure the service has permissions to access the certificate and key.

{
  services.crab-hole.settings.downstream = [
    {
      protocol = "quic";
      listen = "127.0.0.1";
      port = 853;
      certificate = ./dns.example.com.crt;
      key = "/dns.example.com.key";
      # optional
      dns_hostname = "dns.example.com";
      # optional (default = 3000)
      timeout_ms = 3000;
    }
  ];
}

Upstream options

You can set additional options of the underlying DNS server. A full list of all the options can be found in the hickory-dns documentation.

This can look like the following example.

{
  services.crab-hole.settings.upstream.options = {
    validate = false;
  };
}

DNSSEC Issues

Due to an upstream issue of hickory-dns, sites without DNSSEC will not be resolved if validate = true. Only DNSSEC capable sites will be resolved with this setting. To prevent this, set validate = false or omit the [upstream.options].

API

The API allows a user to fetch statistic and information about the crab-hole instance. Basic information is available for everyone, while more detailed information is secured by a key, which will be set with the admin_key option.

{
  services.crab-hole.settings.api = {
    listen = "127.0.0.1";
    port = 8080;
    # optional (default = false)
    show_doc = true; # OpenAPI doc loads content from third party websites
    # optional
    admin_key = "1234";
  };
}

The documentation can be enabled separately for the instance with show_doc. This will then create an additional webserver, which hosts the API documentation. An additional resource is in work in the crab-hole repository.

Troubleshooting

You can check for errors using systemctl status crab-hole or journalctl -xeu crab-hole.service.

Invalid config

Some options of the service are in freeform and not type checked. This can lead to a config which is not valid or cannot be parsed by crab-hole. The error message will tell you what config value could not be parsed. For more information check the example config.

Permission Error

It can happen that the created certificates for TLS, HTTPS or QUIC are owned by another user or group. For ACME for example this would be acme:acme. To give the crab-hole service access to these files, the group which owns the certificate can be added as a supplementary group to the service. For ACME for example:

{
  services.crab-hole.supplementaryGroups = [ "acme" ];
}