zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 7220a04d754177942f34386a585b869de38643ab
parent 61701e9af73a46083ede1a6388798f5c4cb19f57
Author: Katja (ctucx) <git@ctu.cx>
Date: Wed, 21 May 2025 13:00:50 +0200

config/nixos/modules/services: add `knot`
1 file changed, 174 insertions(+), 0 deletions(-)
A
config/nixos/modules/services/knot.nix
|
174
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/services/knot.nix b/config/nixos/modules/services/knot.nix
@@ -0,0 +1,174 @@
+{
+  inputs,
+  povSelf,
+  hostConfig,
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+
+  dnsServerAddresses = isPrimary: lib.flatten (
+    inputs.self.nixosConfigurations
+    |> lib.filterAttrs (hostName: hostConfig: let
+        cfgModule = lib.getAttrFromPath povSelf hostConfig.config;
+      in (cfgModule.enable && cfgModule.primary == isPrimary))
+    |> lib.mapAttrsToList (
+      hostName: hostConfig: [
+          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip6Address != "") inputs.self.hosts."${hostName}".networking.ip6Address)
+          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip4Address != "") inputs.self.hosts."${hostName}".networking.ip4Address)
+      ]
+    )
+  );
+
+  dnsServerSecondaries = (
+    inputs.self.nixosConfigurations
+    |> lib.filterAttrs (hostName: hostConfig: let
+        cfgModule = lib.getAttrFromPath povSelf hostConfig.config;
+      in (cfgModule.enable && !cfgModule.primary))
+    |> lib.mapAttrs(
+      hostName: hostConfig: {
+        address = [
+          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip6Address != "") inputs.self.hosts."${hostName}".networking.ip6Address)
+          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip4Address != "") inputs.self.hosts."${hostName}".networking.ip4Address)
+        ];
+      }
+    )
+  );
+
+in
+{
+
+  options = {
+    enable = {
+      type = types.bool;
+      default = false;
+    };
+
+    primary = {
+      type    = types.bool;
+      default = false;
+    };
+
+    dataDir = {
+      type    = types.str;
+      default = "/var/lib/knot";
+    };
+
+    keyFiles = {
+      type    = types.listOf types.path;
+      default = [];
+    };
+
+    zones = {
+      type    = (pkgs.formats.yaml { }).type;
+      default = {};
+    };
+
+    extraACL = {
+      type    = (pkgs.formats.yaml { }).type;
+      default = {};
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    networking.firewall.allowedTCPPorts = [ 53 ];
+    networking.firewall.allowedUDPPorts = [ 53 ];
+
+    systemd.tmpfiles.settings = {
+      knotDataDir."${cfg.dataDir}".d = {
+        group = "knot";
+        user  = "knot";
+        mode  = "770";
+        age   = "-";
+      };
+    };
+
+    services.knot = let
+      primaryAddresses   = dnsServerAddresses true;
+      secondaryAddresses = dnsServerAddresses false;
+      secondaries        = dnsServerSecondaries;
+
+    in {
+	    enable   = true;
+	    keyFiles = lib.mkIf (cfg.keyFiles != []) cfg.keyFiles;
+	    settings = {
+	      log.syslog.any = "info";
+
+        server.listen = [
+          (lib.mkIf (hostConfig.networking.ip6Address != "") "${hostConfig.networking.ip6Address}@53")
+          (lib.mkIf (hostConfig.networking.ip4Address != "") "${hostConfig.networking.ip4Address}@53")
+          "::1@53"
+        ];
+
+        mod-rrl.default.rate-limit = 200;
+        mod-rrl.default.slip       = 2;
+
+        remote = { primary.address = primaryAddresses; } // secondaries;
+
+        acl = {
+          allowTransfer = lib.mkIf (secondaryAddresses != []) {
+            address = secondaryAddresses;
+            action  = "transfer";
+          };
+
+          allowNotify.address   = primaryAddresses;
+          allowNotify.action    = "notify";
+        } // cfg.extraACL;
+
+        template = let
+          notify = {
+            acl          = lib.mkIf (config.services.knot.settings.acl ? allowTransfer) "allowTransfer";
+            notify       = lib.mkIf (config.services.knot.settings.acl ? allowTransfer) (builtins.attrNames secondaries);
+          };
+
+          catalog = {
+            catalog-role = "member";
+            catalog-zone = "catalog.";
+          };
+
+        in {
+
+          default = {
+            semantic-checks = true;
+            global-module   = "mod-rrl/default";
+          };
+
+          notifyZone = notify;
+          nixZone = notify // catalog;
+
+          secondaryZone = {
+            master = "primary";
+            acl    = "allowNotify";
+
+            journal-content = "all";
+
+            zonefile-sync   = -1;
+            zonefile-load   = "none";
+          };
+        };
+
+        zone = (if !cfg.primary then {
+          "catalog.".catalog-role     = "interpret";
+          "catalog.".catalog-template = "secondaryZone";
+          "catalog.".template         = "secondaryZone";
+        } else {
+          "catalog.".catalog-role  = "generate";
+          "catalog.".template      = "notifyZone";
+        }) // (lib.mapAttrs (name: zone: zone // {
+          template = "nixZone";
+          acl      = lib.mkIf (zone ? acl) (
+            if (config.services.knot.settings.acl ? allowTransfer) then
+              lib.flatten [ [ "allowTransfer" ] zone.acl ]
+            else
+              zone.acl
+          );
+        }) cfg.zones);
+	    };
+    };
+  };
+
+}