ctucx.git: nixfiles

ctucx' nixfiles

commit 60be52f877c7e3ded9f2faada3f74a07e3028f08
parent 8fe84450b8325bc43be2a64b520d35ca1150ee55
Author: Katja (ctucx) <git@ctu.cx>
Date: Fri, 28 Feb 2025 00:52:18 +0100

modules/linux/dns: replace `bind` with `knot`, support zone-transfer to slaves
3 files changed, 152 insertions(+), 83 deletions(-)
M
configurations/linux/services/default.nix
|
1
-
M
configurations/linux/services/dns.nix
|
106
++++++++++++++++++++++++++++++++++++-------------------------------------------
M
modules/linux/dns.nix
|
128
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
diff --git a/configurations/linux/services/default.nix b/configurations/linux/services/default.nix
@@ -22,7 +22,6 @@
   ];
 
   ctucxConfig.monitoring.exporters.enable  = (lib.mkDefault (if (config.networking.primaryIP != "") || (config.networking.primaryIP4 != "") then true else false));
-  ctucxConfig.services.dnsServer.enable    = (lib.mkDefault (builtins.elem "dnsServer" config.deployment.tags));
   ctucxConfig.services.resticServer.enable = (lib.mkDefault (builtins.elem "resticServer" config.deployment.tags));
 
 } 
\ No newline at end of file
diff --git a/configurations/linux/services/dns.nix b/configurations/linux/services/dns.nix
@@ -1,78 +1,68 @@
 { nodes, config, lib, pkgs, ...}:
 
-let
-  cfg = config.ctucxConfig.services.dnsServer;
-
-in {
-
-  options = {
-    ctucxConfig.services.dnsServer = {
-      enable = lib.mkEnableOption "dns";
-    };
-  };
-
-  config = lib.mkIf cfg.enable {
-    dns = {
-      enable      = true;
-      allZones    = with pkgs.dns.lib.combinators; let
-        CAA = [ { issuerCritical = false; tag = "issue"; value = "letsencrypt.org"; } ];
-        NS  = [ "ns1.ctu.cx." "ns2.ctu.cx." ];
-        SOA = {
-          nameServer = "ns1.ctu.cx.";
-          adminEmail = "dns@ctu.cx"; # Email address with a real `@`!
-          serial     = lib.toInt ("2023" + "03" + "04" + "1");
-        };
-
-      in {
+{
+
+  dns = {
+    enable    = lib.mkDefault (builtins.elem "dnsServer" config.deployment.tags);
+    primary   = lib.mkDefault (config.networking.hostName == "hector");
+    allZones  = with pkgs.dns.lib.combinators; let
+      CAA = [ { issuerCritical = false; tag = "issue"; value = "letsencrypt.org"; } ];
+      NS  = [ "ns1.ctu.cx." "ns2.ctu.cx." ];
+      SOA = {
+        nameServer = "ns1.ctu.cx.";
+        adminEmail = "dns@ctu.cx"; # Email address with a real `@`!
+        serial     = lib.toInt ("2023" + "03" + "04" + "1");
+      };
 
-        "ctu.cx" = {
-          inherit SOA NS CAA;
+    in {
+      "ctu.cx" = {
+        inherit SOA NS CAA;
 
-          subdomains = {
-            ns1          = (host nodes.hector.config.networking.primaryIP4      nodes.hector.config.networking.primaryIP);
-            ns2          = (host nodes.wanderduene.config.networking.primaryIP4 nodes.wanderduene.config.networking.primaryIP);
+        subdomains = {
+          ns1          = (host nodes.hector.config.networking.primaryIP4      nodes.hector.config.networking.primaryIP);
+          ns2          = (host nodes.wanderduene.config.networking.primaryIP4 nodes.wanderduene.config.networking.primaryIP);
 
-            _atproto.TXT              = [ "did=did:plc:zaeuok3fmh2pcp4cjiicku4i" ];
-          };
+          _atproto.TXT = [ "did=did:plc:zaeuok3fmh2pcp4cjiicku4i" ];
+          test.TXT = [ "test uwu"];
         };
+      };
 
-        "wifionic.de" = {
-          inherit SOA NS CAA;
-        };
+      "wifionic.de" = {
+        inherit SOA NS CAA;
+      };
 
-        "trans-agenda.de" = {
-          inherit SOA NS CAA;
-        };
+      "trans-agenda.de" = {
+        inherit SOA NS CAA;
+      };
 
-        "katja.wtf" = {
-          inherit SOA NS CAA;
-        };
+      "katja.wtf" = {
+        inherit SOA NS CAA;
+      };
 
-        "ctucx.de" = {
-          inherit SOA NS CAA;
-        };
+      "ctucx.de" = {
+        inherit SOA NS CAA;
+      };
 
-        "zuggeschmack.de" = {
-          inherit SOA NS CAA;
-        };
+      "zuggeschmack.de" = {
+        inherit SOA NS CAA;
+      };
 
-        "thein.ovh" = {
-          inherit SOA NS CAA;
-        };
+      "thein.ovh" = {
+        inherit SOA NS CAA;
+      };
 
-        "flauschehorn.sexy" = {
-          inherit SOA NS CAA;
+      "flauschehorn.sexy" = {
+        inherit SOA NS CAA;
 
-          MX  = with mx; [ (mx 10 "rx300.kunbox.net.") ];
-          TXT = [ "v=spf1 mx ~all" ];
+        MX  = with mx; [ (mx 10 "rx300.kunbox.net.") ];
+        TXT = [ "v=spf1 mx ~all" ];
 
-          subdomains = {
-            _dmarc.TXT            = [ "v=DMARC1; p=quarantine; rua=mailto:hostmaster@kunbox.net; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r" ];
-            "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh5Ym9PO7r+wdOIKfopvHzn3KU3qT6IlCG/gvvbmIqoeFQfRbAe3gQmcG6RcLue55cJQGhI6y2r0lm59ZeoHR40aM+VabAOlplekM7xWmoXb/9vG2OZLIqAyF4I+7GQmTN6B9keBHp9SWtDUkI0B0G9neZ5MkXJP705M0duxritqQlb4YvCZwteHiyckKcg9aE9j+GF2EEawBoVDpoveoB3+wgde3lWEUjjwKFtXNXxuN354o6jgXgPNWtIEdPMLfK/o0CaCjZNlzaLTsTegY/+67hdHFqDmm8zXO9s+Xiyfq7CVq21t7wDhQ2W1agj+up6lH82FMh5rZNxJ6XB0yQIDAQAB" ];
-          };
+        subdomains = {
+          _dmarc.TXT            = [ "v=DMARC1; p=quarantine; rua=mailto:hostmaster@kunbox.net; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r" ];
+          "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh5Ym9PO7r+wdOIKfopvHzn3KU3qT6IlCG/gvvbmIqoeFQfRbAe3gQmcG6RcLue55cJQGhI6y2r0lm59ZeoHR40aM+VabAOlplekM7xWmoXb/9vG2OZLIqAyF4I+7GQmTN6B9keBHp9SWtDUkI0B0G9neZ5MkXJP705M0duxritqQlb4YvCZwteHiyckKcg9aE9j+GF2EEawBoVDpoveoB3+wgde3lWEUjjwKFtXNXxuN354o6jgXgPNWtIEdPMLfK/o0CaCjZNlzaLTsTegY/+67hdHFqDmm8zXO9s+Xiyfq7CVq21t7wDhQ2W1agj+up6lH82FMh5rZNxJ6XB0yQIDAQAB" ];
         };
-
       };
+
     };
   };
 
diff --git a/modules/linux/dns.nix b/modules/linux/dns.nix
@@ -10,6 +10,21 @@ in {
   options.dns = {
     enable = mkEnableOption "nix-powered DNS";
 
+    primary = lib.mkOption {
+      type    = lib.types.bool;
+      default = true;
+    };
+
+    zonesDir = lib.mkOption {
+      type    = lib.types.str;
+      default = "zones";
+    };
+
+    dataDir = lib.mkOption {
+      type    = lib.types.str;
+      default = "/var/lib/knot";
+    };
+
     # contains dns entries defined on the local host
     zones = mkOption {
       type    = lib.types.attrsOf pkgs.dns.lib.types.subzone;

@@ -21,12 +36,6 @@ in {
       type    = lib.types.attrsOf pkgs.dns.lib.types.zone;
       default = {};
     };
-
-    # zones not generated by nix-dns, for example secondaries
-    extraZones = mkOption {
-      type    = lib.types.listOf lib.types.attrs;
-      default = [];
-    };
   };
 
   config = mkIf cfg.enable {

@@ -40,24 +49,95 @@ in {
       ) nodes
     );
 
-    systemd.services.bind.preStart = ''
-      mkdir -p /var/lib/bind
-      chown named /var/lib/bind
-    '';
-
-    services.bind = {
-      enable = true;
-      zones = (
-        mapAttrsToList (
-          name: zone: {
-            inherit name;
-            master = true;
-            slaves = [ "any" ];
-            file = pkgs.dns.util."${currentSystem}".writeZone name zone;
-          }
-        ) cfg.allZones
-      ) ++ cfg.extraZones;
-    };
+  	environment.etc = (lib.mapAttrs' (name: zone: {
+  	    name = "${cfg.zonesDir}/${name}.zone";
+  	    value = { source = pkgs.dns.util."${currentSystem}".writeZone name zone; };
+  	}) cfg.allZones);
+
+  	services.knot = {
+	    enable = true;
+	    keyFiles = [];
+	    settings = {
+    		log.syslog.any = "info";
+
+    		server = {
+		      automatic-acl = true;
+	  	    listen        = [
+	  	      (lib.mkIf (config.networking.primaryIP  != "") "${config.networking.primaryIP}@53") 
+	  	      (lib.mkIf (config.networking.primaryIP4 != "") "${config.networking.primaryIP4}@53") 
+	  	    ];
+		    };
+
+    		remote = [
+    		  {
+    		    id     = "primary";
+    		    address = lib.concatLists (
+    		      lib.mapAttrsToList (
+                name: node: [
+                  (lib.mkIf (node.config.networking.primaryIP  != "") node.config.networking.primaryIP)
+                  (lib.mkIf (node.config.networking.primaryIP4 != "") node.config.networking.primaryIP4)
+                ]
+    		      ) (lib.filterAttrs (name: node: node.config.dns.enable && node.config.dns.primary) nodes)
+    		    );
+    		  }
+    		  {
+    		    id     = "secondary";
+    		    address = lib.concatLists (
+    		      lib.mapAttrsToList (
+                name: node: [
+                  (lib.mkIf (node.config.networking.primaryIP  != "") node.config.networking.primaryIP)
+                  (lib.mkIf (node.config.networking.primaryIP4 != "") node.config.networking.primaryIP4)
+                ]
+    		      ) (lib.filterAttrs (name: node: node.config.dns.enable && !node.config.dns.primary) nodes)
+    		    );
+    		  }
+    		];
+
+	    	template.default = {
+  		    storage = "${cfg.dataDir}/zones";
+  		    zonefile-sync = -1;
+	  	    zonefile-load = "difference-no-serial";
+		      journal-content = "all";
+		      notify = lib.mkIf cfg.primary    "secondary";
+		      master = lib.mkIf (!cfg.primary) "primary";
+    		};
+  
+		    zone = lib.mapAttrs (name: zone: {}) cfg.allZones;
+	    };
+  	};
+
+  	systemd.tmpfiles.settings = {
+ 	    dataDir."${cfg.dataDir}".d = {
+  	  	group = "knot";
+  	  	user  = "knot";
+  	  	mode  = "770";
+  	  	age   = "-";
+      };
+
+  	  zones."${cfg.dataDir}/zones".d = {
+  		  group = "knot";
+  		  user  = "knot";
+  		  mode  = "770";
+  		  age   = "-";
+  	  };
+  	};
+
+  	systemd.services.knot = lib.mkIf cfg.primary {
+  	  reloadTriggers = lib.mapAttrsToList (name: zone: pkgs.dns.util."${currentSystem}".writeZone name zone) cfg.allZones;
+
+  	  preStart = ''
+  	    set -euo pipefail
+  	    cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/zones
+  	    chmod -R 770 ${cfg.dataDir}/zones
+  	  ''; 
+
+  	  serviceConfig.ExecReload = lib.mkForce (pkgs.writeShellScript "knot-reload" ''
+    		set -eou pipefail
+    		cp --dereference /etc/${cfg.zonesDir}/* ${cfg.dataDir}/zones
+    		chmod -R 770 ${cfg.dataDir}/zones
+  	  	${config.services.knot.package}/bin/knotc reload
+  	  '');
+  	};
   };
 
 }