{ 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; 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; }; }