Janik-Haag / NixOS-DNS

Manage your dns zones with NixOS
MIT License
119 stars 3 forks source link

Setting SOA records using `subDomains` is broken #17

Open Rubikoid opened 1 month ago

Rubikoid commented 1 month ago

Simple setup with defining SOA using subDomains (instead of extraConfig as in example) don't builds zone files:

(
  let
    rootZone = "example.org";
  in
  {
    networking.domains = {
      enable = true;
      defaultTTL = 86400; # 24h
      baseDomains."nodes.${rootZone}" = { };
      baseDomains."${rootZone}" = { };
      subDomains."${rootZone}".soa.data = {
        mname = "a.misconfigured.dns.server.invalid";
        rname = "hostmaster\.${rootZone}";
        serial = 0;
        refresh = 10800;
        retry = 3600;
        expire = 604800;
      };
    };
  }
)
 at /nix/store/d4vvgffq1k76dri89sji04qc69ybjqkd-source/utils/zonefiles.nix:79:25:

   78|           lib.mapAttrsToList (
   79|             recordType: record:
     |                         ^
   80|             (builtins.map (

error: value is a set while a list was expected

Wherein it's impossible to pass list in soa.data, because it is null or submodule.

Full example to reproduce: nix build ".#dns.zoneFiles" -v --show-trace

{
  description = "A example on how one can use nixos-dns";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nixos-dns.url = "github:Janik-Haag/nixos-dns";
    nixos-dns.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs =
    inputs@{ self, nixpkgs, nixos-dns, }:
    let
      forAllSystems = nixpkgs.lib.genAttrs [
        "x86_64-linux"
        "aarch64-linux"
      ];
      dnsConfig = {
        inherit (self) nixosConfigurations;
      };
    in
    {
      nixosConfigurations = {
        host1 = nixpkgs.lib.nixosSystem {
          system = "x86_64-linux";
          modules = [
            nixos-dns.nixosModules.dns
            (
              let
                rootZone = "example.org";
              in
              {
                networking.domains = {
                  enable = true;
                  defaultTTL = 86400; # 24h
                  baseDomains."nodes.${rootZone}" = { };
                  baseDomains."${rootZone}" = { };
                  subDomains."${rootZone}".soa.data = {
                    mname = "a.misconfigured.dns.server.invalid";
                    rname = "hostmaster\.${rootZone}";
                    serial = 0;
                    refresh = 10800;
                    retry = 3600;
                    expire = 604800;
                  };
                };
              }
            )
          ];
        };
      };

      # nix eval .#dnsDebugConfig
      dnsDebugConfig = nixos-dns.utils.debug.config dnsConfig;

      packages = forAllSystems (
        system:
        let
          generate = nixos-dns.utils.generate nixpkgs.legacyPackages.${system};
        in
        {
          # nix build .#zoneFiles
          dns.zoneFiles = generate.zoneFiles dnsConfig;
        }
      );
    };
}
Janik-Haag commented 1 month ago

Hey, this is still an open to-do, https://github.com/Janik-Haag/NixOS-DNS/blob/main/modules/nixos.nix#L91 I don't really know how to handle the merge operation for soa records, and since they aren't host specific, I think it's reasonable to enforce them being in extraConfig only. Do you have some reason you'd want to avoid extraConfig, or some suggestion how merging here should be handled?

Btw a bit tangential but something I should document at some point is that you can use self.lastModified (with flakes) or (builtins.fetchGit ./.).lastModified (without flakes) and you get the unix-millis timestamp of your last git commit in the repo which is perfect as SOA serial.

Rubikoid commented 1 month ago

Hey, this is still an open to-do,

Oh, sorry, I missed this part in sources ;(

Do you have some reason you'd want to avoid extraConfig

Not really. In my case I put all the DNS settings into one machine's config (I know this is not how library should be used, but this way was a little more convenient in my setup), so it was quite logical to keep all the records in one place and do not split between two attrsets.

some suggestion how merging here should be handled

Maybe allow specifying only one soa record per global dns config, and if the merging needed (i.e. user created more than one record) - throw error? But I'm not sure this is a good path.

is that you can use self.lastModified (with flakes)

This is a great idea, thanks!