From 8f137c28230623259a964484adcf31fe00756594 Mon Sep 17 00:00:00 2001 From: Azat Bahawi Date: Sat, 17 Dec 2022 16:39:09 +0300 Subject: 2022-12-17 --- modules/nixos/unbound.nix | 197 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 modules/nixos/unbound.nix (limited to 'modules/nixos/unbound.nix') diff --git a/modules/nixos/unbound.nix b/modules/nixos/unbound.nix new file mode 100644 index 0000000..8c40291 --- /dev/null +++ b/modules/nixos/unbound.nix @@ -0,0 +1,197 @@ +{ + 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 { + 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); + + 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" + ]; + + private-domain = cfg.domain; + private-address = with config.nixfiles.modules.wireguard; [ + ipv4.subnet + ipv6.subnet + ]; + + domain-insecure = cfg.domain; + + prefetch = true; + prefetch-key = true; + + hide-identity = true; + hide-version = true; + + extended-statistics = true; + + 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.unbound; { + backend = "redis"; + redis-server-host = bind; + redis-server-port = port; + }; + }; + + localControlSocketPath = "/run/unbound/unbound.socket"; + }; + + redis = { + servers.unbound = { + enable = true; + bind = "127.0.0.1"; + port = 6379; + }; + vmOverCommit = mkForce true; + }; + + prometheus.exporters = { + unbound = { + enable = true; + listenAddress = mkDefault this.wireguard.ipv4.address; + port = 9167; + fetchType = "uds"; + controlInterface = config.services.unbound.localControlSocketPath; + inherit (config.services.unbound) group user; + }; + + redis = { + enable = true; + listenAddress = mkDefault this.wireguard.ipv4.address; + port = mkDefault 9121; + extraFlags = with config.services.redis.servers.unbound; [ + "--redis.addr=redis://${bind}:${toString port}" + "--redis.user=${user}" + ]; + }; + }; + }; + + systemd = { + services = { + unbound.after = ["unbound-adblock-update.service"]; + + unbound-adblock-update = { + serviceConfig = with config.services.unbound; { + Type = "oneshot"; + User = user; + Group = group; + ExecStart = let + pkg = with pkgs; + writeShellApplication { + name = "unbound-adblock-update"; + runtimeInputs = [curl package]; + text = '' + curl \ + "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=unbound&showintro=0&mimetype=plaintext" \ + >${adblock-conf} + + if [[ -f "${localControlSocketPath}" ]]; then + unbound-control reload + fi + ''; + }; + in "${pkg}/bin/unbound-adblock-update"; + }; + }; + }; + + timers.unbound-adblock-update = { + requires = ["network-online.target"]; + timerConfig = { + OnUnitActiveSec = "1d"; + Unit = "unbound-adblock-update.service"; + }; + wantedBy = ["timers.target"]; + }; + }; + }; +} -- cgit 1.4.1