From bb0b81be73fcb81b59516e6bac3bf391d39970fb Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Sun, 1 Mar 2026 22:57:01 +0100 Subject: [PATCH] nameservers/public: Init module --- modules/nixos/services/nameservers/public.nix | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 modules/nixos/services/nameservers/public.nix diff --git a/modules/nixos/services/nameservers/public.nix b/modules/nixos/services/nameservers/public.nix new file mode 100644 index 0000000..0841d75 --- /dev/null +++ b/modules/nixos/services/nameservers/public.nix @@ -0,0 +1,88 @@ +{ + config, + inputs, + lib, + allHosts, + ... +}: +let + cfg = config.custom.services.nameservers.public; + netCfg = config.custom.networking; + + zoneData = + zone: + let + mkSubdomain = + { name, address }: + { + inherit name; + value.A = [ address ]; + }; + + serviceRecords = + allHosts + |> lib.attrValues + |> lib.concatMap ( + host: + host.config.custom.services.caddy.virtualHosts + |> lib.attrValues + |> lib.map (vHost: vHost.domain) + |> lib.filter (domain: domain |> lib.hasSuffix "${zone}") + |> lib.map (domain: domain |> lib.removeSuffix ".${zone}" |> lib.removeSuffix "${zone}") # In case the domain is the root domain + |> lib.map (name: { + inherit name; + inherit (host.config.custom.networking.underlay) address; + }) + ); + + nsRecords = + allHosts + |> lib.attrValues + |> lib.filter (host: host.config.custom.services.nameservers.public.enable) + |> lib.map (host: { + name = host.config.custom.networking.hostName; + inherit (host.config.custom.networking.underlay) address; + }); + in + inputs.dns.lib.toString zone { + SOA = { + nameServer = "${netCfg.hostName}.${zone}."; + adminEmail = "hostmaster@sstork.dev"; + serial = 1; + }; + + NS = nsRecords |> lib.map ({ name, ... }: "${name}.${zone}."); + + A = serviceRecords |> lib.filter ({ name, ... }: name == "") |> lib.map (record: record.address); + + subdomains = + serviceRecords + |> lib.filter ({ name, ... }: name != "") + |> (subRecords: nsRecords ++ subRecords) + |> lib.map mkSubdomain + |> lib.listToAttrs; + }; +in +{ + options.custom.services.nameservers.public = { + enable = lib.mkEnableOption ""; + zones = lib.mkOption { + type = lib.types.nonEmptyListOf lib.types.nonEmptyStr; + default = [ ]; + }; + }; + + config = lib.mkIf cfg.enable { + services.nsd = { + enable = true; + interfaces = [ netCfg.underlay.interface ]; + zones = + cfg.zones + |> lib.map (zone: { + name = zone; + value.data = zoneData zone; + }) + |> lib.listToAttrs; + }; + }; +}