{ config, lib, pkgs, this, ... }: with lib; let cfg = config.nixfiles.modules.unbound; in { options.nixfiles.modules.unbound = { enable = mkEnableOption "Unbound"; domain = mkOption { description = "Domain name sans protocol scheme."; type = with types; str; default = config.networking.domain; }; }; config = let adblock-conf = "${config.services.unbound.stateDir}/adblock.conf"; in mkIf cfg.enable { ark.directories = [config.services.unbound.stateDir]; nixfiles.modules = { redis.enable = true; promtail.filters = [ { match = { selector = ''{syslog_identifier="unbound"} |~ " start | stopped |.*in-addr.arpa."''; action = "drop"; }; } { match = { selector = ''{syslog_identifier="unbound"} |= "reply:"''; stages = [{static_labels.dns = "reply";}]; }; } { match = { selector = ''{syslog_identifier="unbound"} |~ "redirect |always_null|always_nxdomain"''; stages = [{static_labels.dns = "block";}]; }; } ]; }; services = { unbound = { enable = true; package = pkgs.unbound-with-systemd.override { withRedis = true; withTFO = true; }; settings = { server = { interface = with this.wireguard; [ "127.0.0.1" "::1" ipv4.address ipv6.address ]; local-zone = concatLists (mapAttrsToList (h: _: [''"${h}.${cfg.domain}" redirect'']) my.configurations); local-data = concatLists (mapAttrsToList (hostname: let domain = "${hostname}.${cfg.domain}"; in attr: (optionals (hasAttr "wireguard" attr) (with attr.wireguard; [ ''"${domain} 604800 IN A ${ipv4.address}"'' ''"${domain} 604800 IN AAAA ${ipv6.address}"'' ''"${domain}. A ${ipv4.address}"'' ''"${domain}. AAAA ${ipv6.address}"'' ] ++ concatMap (domain: [ ''"${domain}. A ${ipv4.address}"'' ''"${domain}. AAAA ${ipv6.address}"'' ]) attr.domains))) my.configurations); local-data-ptr = concatLists (mapAttrsToList (hostname: let domain = "${hostname}.${cfg.domain}"; in attr: (optionals (hasAttr "wireguard" attr) (with attr.wireguard; [ ''"${ipv4.address} ${domain}"'' ''"${ipv6.address} ${domain}"'' ] ++ concatMap (domain: [ ''"${ipv4.address} ${domain}"'' ''"${ipv6.address} ${domain}"'' ]) attr.domains))) my.configurations); private-domain = map (domain: "${domain}.") [ cfg.domain "local" ]; private-address = with config.nixfiles.modules.wireguard; [ ipv4.subnet ipv6.subnet ]; access-control = with config.nixfiles.modules.wireguard; [ "0.0.0.0/0 refuse" "::/0 refuse" "127.0.0.0/8 allow" "::1/128 allow" "${ipv4.subnet} allow" "${ipv6.subnet} allow" ]; cache-min-ttl = 0; serve-expired = true; serve-expired-reply-ttl = 0; prefetch = true; prefetch-key = true; hide-identity = true; hide-version = true; extended-statistics = true; log-replies = false; log-tag-queryreply = false; log-local-actions = false; verbosity = 0; include = ''"${adblock-conf}"''; }; forward-zone = [ { name = "."; forward-tls-upstream = true; forward-addr = let mkDnsOverTls = ips: auth: map (ip: concatStrings [ip "@" auth]) ips; in mkDnsOverTls dns.const.quad9.default "853#dns.quad9.net"; } ]; cachedb = with config.services.redis.servers.default; { backend = "redis"; redis-server-host = bind; redis-server-port = port; }; }; enableRootTrustAnchor = true; localControlSocketPath = "/run/unbound/unbound.socket"; }; prometheus.exporters.unbound = { enable = true; listenAddress = mkDefault this.wireguard.ipv4.address; port = 9167; inherit (config.services.unbound) group user; unbound.host = "unix://${config.services.unbound.localControlSocketPath}"; }; }; systemd = { services = { unbound.after = ["unbound-adblock-update.service"]; unbound-adblock-update = { serviceConfig = with config.services.unbound; { Type = "oneshot"; User = user; Group = group; ExecStart = getExe (pkgs.writeShellApplication { name = "unbound-adblock-update"; runtimeInputs = [pkgs.curl package]; text = '' curl -s \ "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=unbound&showintro=0&mimetype=plaintext" \ >${adblock-conf} if [[ -f "${localControlSocketPath}" ]]; then unbound-control reload fi ''; }); }; }; }; timers.unbound-adblock-update = { requires = ["network-online.target"]; timerConfig = { OnCalendar = "daily"; Persistent = true; Unit = "unbound-adblock-update.service"; }; wantedBy = ["timers.target"]; }; }; boot.kernel.sysctl."net.ipv4.tcp_fastopen" = mkOverride 200 3; }; }