diff options
Diffstat (limited to 'modules/unbound-ng.nix')
-rw-r--r-- | modules/unbound-ng.nix | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/modules/unbound-ng.nix b/modules/unbound-ng.nix new file mode 100644 index 0000000..3d3c6da --- /dev/null +++ b/modules/unbound-ng.nix @@ -0,0 +1,185 @@ +{ + config, + inputs, + lib, + pkgs, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.unbound-ng; +in +{ + options.nixfiles.modules.unbound-ng = { + enable = mkEnableOption "Unbound"; + + domain = mkOption { + description = "Domain name sans protocol scheme."; + type = with types; str; + default = config.networking.domain; + }; + }; + + config = 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; + }; + + checkconf = true; + settings = { + server = { + module-config = ''"respip validator iterator"''; + + interface = with this.wireguard-ng; [ + "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-ng" attr) ( + with attr.wireguard-ng; + [ + "\"${domain} 604800 IN A ${ipv4.address}\"" + "\"${domain} 604800 IN AAAA ${ipv6.address}\"" + "\"${domain}. A ${ipv4.address}\"" + "\"${domain}. AAAA ${ipv6.address}\"" + ] + ++ (optionals (hasAttr "domains" attr) ( + 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-ng" attr) ( + with attr.wireguard-ng; + [ + "\"${ipv4.address} ${domain}\"" + "\"${ipv6.address} ${domain}\"" + ] + ++ (optionals (hasAttr "domains" attr) ( + 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-ng; [ + ipv4.subnet + ipv6.subnet + ]; + + access-control = with config.nixfiles.modules.wireguard-ng; [ + "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; + }; + + forward-zone = [ + { + name = "."; + forward-tls-upstream = true; + forward-addr = dns.mkDoT dns.const.quad9.ecs; + } + ]; + + cachedb = with config.services.redis.servers.default; { + backend = "redis"; + redis-server-host = bind; + redis-server-port = port; + }; + + rpz = { + name = "hagezi.pro"; + zonefile = "hagezi.pro"; + url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/rpz/pro.txt"; + }; + }; + + enableRootTrustAnchor = true; + + localControlSocketPath = "/run/unbound/unbound.socket"; + }; + + prometheus.exporters.unbound = { + enable = true; + listenAddress = mkDefault this.wireguard-ng.ipv4.address; + port = 9167; + inherit (config.services.unbound) group user; + unbound.host = "unix://${config.services.unbound.localControlSocketPath}"; + }; + }; + + boot.kernel.sysctl."net.ipv4.tcp_fastopen" = mkOverride 200 3; + + topology = with cfg; { + nodes.${this.hostname}.services.unbound = { + name = "Unbound"; + icon = "${inputs.homelab-svg-assets}/assets/unbound.svg"; + details.listen.text = concatMapStringsSep "\n" (i: "${i}:53") ( + filter (i: i != "127.0.0.1" && i != "::1") config.services.unbound.settings.server.interface + ); + }; + }; + }; +} |