From 1db71f86db2d251b9396f3a019630a11992a5d2b Mon Sep 17 00:00:00 2001 From: Julien Malka Date: Mon, 12 Aug 2024 18:15:30 +0200 Subject: [PATCH] feat: add dns module --- lib/default.nix | 37 ++++++++++++---------- machines/gustave/default.nix | 2 +- machines/gustave/nsd.nix | 48 ++++++++++++++++++++++++++++ modules/dns/default.nix | 61 ++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 machines/gustave/nsd.nix create mode 100644 modules/dns/default.nix diff --git a/lib/default.nix b/lib/default.nix index 0094741..73c04f4 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,7 +1,16 @@ inputs: final: _prev: with builtins; - +let + evalMeta = + raw: + (_prev.evalModules { + modules = [ + (import ../modules/meta/default.nix) + { machine.meta = raw; } + ]; + }).config.machine.meta; +in rec { importConfig = path: @@ -37,29 +46,25 @@ rec { }; }; - evalMeta = - raw: - (_prev.evalModules { - modules = [ - (import ../modules/meta/default.nix) - { machine.meta = raw; } - ]; - }).config.machine.meta; + listToAttrsWithMerge = + l: + mapAttrs (_: v: _prev.fold (elem: acc: elem.value // acc) { } v) (builtins.groupBy (e: e.name) l); + + mapAttrsWithMerge = f: set: listToAttrsWithMerge (map (attr: f attr set.${attr}) (attrNames set)); snowfield = mapAttrs ( name: _value: + let + machineF = import (../machines + "/${name}/default.nix"); + in evalMeta - (import (../machines + "/${name}/default.nix") { - inherit inputs; - config = null; - pkgs = null; - lib = null; - modulesPath = null; - }).machine.meta + (machineF ((mapAttrs (_: _: null) (builtins.functionArgs machineF)) // { inherit inputs; })) + .machine.meta ) (final.filterAttrs (_: v: v == "directory") (readDir ../machines)); dns = import ./dns.nix { lib = final; dnsLib = (import inputs.dns).lib; }; + } diff --git a/machines/gustave/default.nix b/machines/gustave/default.nix index c436522..d30b3b6 100644 --- a/machines/gustave/default.nix +++ b/machines/gustave/default.nix @@ -1,11 +1,11 @@ { pkgs, inputs, ... }: - { imports = [ ../../users/default.nix ../../users/julien.nix ./hardware.nix ./home-julien.nix + ./nsd.nix ]; machine.meta = { diff --git a/machines/gustave/nsd.nix b/machines/gustave/nsd.nix new file mode 100644 index 0000000..9ba262d --- /dev/null +++ b/machines/gustave/nsd.nix @@ -0,0 +1,48 @@ +{ + config, + lib, + inputs, + nixosConfigurations, + ... +}: +let + zonesToList = lib.mapAttrsToList (name: value: { ${name} = value; }); + zonesFromConfig = lib.mkMerge ( + lib.fold (elem: acc: acc ++ (zonesToList elem.config.machine.meta.zones)) [ ] ( + lib.attrValues nixosConfigurations + ) + ); + dnsLib = (import inputs.dns).lib; + evalZones = + zones: + (lib.evalModules { + modules = [ + { + options = { + zones = lib.mkOption { + type = lib.types.attrsOf dnsLib.types.zone; + description = "DNS zones"; + }; + }; + config = { + inherit zones; + }; + } + ]; + }).config.zones; + +in + +{ + services.nsd = { + enable = true; + interfaces = [ + config.machine.meta.ips.public.ipv4 + config.machine.meta.ips.public.ipv6 + ]; + zones = lib.mapAttrs (_: value: { + data = builtins.toString value; + provideXFR = [ "192.168.0.0/21 NOKEY" ]; + }) (evalZones zonesFromConfig); + }; +} diff --git a/modules/dns/default.nix b/modules/dns/default.nix new file mode 100644 index 0000000..414d175 --- /dev/null +++ b/modules/dns/default.nix @@ -0,0 +1,61 @@ +{ + lib, + config, + inputs, + ... +}: +let + cfg = config.machine.meta; + allowedDomains = [ + "luj.fr" + "julienmalka.me" + "malka.family" + "luj" + "luj-static.page" + ]; + + isVPNDomain = domain: lib.dns.domainToZone [ "luj" ] domain != null; + dnsLib = (import inputs.dns).lib; + SOA = { + nameServer = "ns"; + adminEmail = "dns@malka.sh"; + serial = 0; + }; + defaults = { + inherit SOA; + }; +in +with lib; +{ + + options = { + machine.meta.zones = mkOption { + type = types.attrsOf dnsLib.types.zone; + default = { }; + }; + }; + + config = + let + # list of domains that are defined in the current configuration throught virtualHosts + domains = lib.dns.domainsFromConfiguration allowedDomains config; + # AttrSet domain -> { records } + recordsPerDomain = map ( + domain: + mapAttrs' ( + n: v: + nameValuePair (lib.dns.domainToZone allowedDomains n) ( + let + subdomain = lib.dns.getDomainPrefix allowedDomains n; + in + (if elem subdomain allowedDomains then v else { subdomains."${subdomain}" = v; }) // defaults + ) + ) (lib.dns.domainToRecords domain cfg (isVPNDomain domain)) + ) domains; + in + + { + machine.meta.zones = lib.mkMerge recordsPerDomain; + }; + +}