diff --git a/hosts/homeserver/default.nix b/hosts/homeserver/default.nix index 12b1f8b..56e99e6 100644 --- a/hosts/homeserver/default.nix +++ b/hosts/homeserver/default.nix @@ -21,6 +21,7 @@ }; services = { + recursive-nameserver.enable = true; private-nameserver.enable = true; syncthing = { diff --git a/hosts/vps-ns/default.nix b/hosts/vps-ns/default.nix index c7c73ea..89f5724 100644 --- a/hosts/vps-ns/default.nix +++ b/hosts/vps-ns/default.nix @@ -21,6 +21,7 @@ }; services = { + recursive-nameserver.enable = true; private-nameserver.enable = true; public-nameserver = { enable = true; diff --git a/modules/nixos/networking/overlay.nix b/modules/nixos/networking/overlay.nix index 3783352..42b7afa 100644 --- a/modules/nixos/networking/overlay.nix +++ b/modules/nixos/networking/overlay.nix @@ -63,8 +63,11 @@ in default = allHosts |> lib.attrValues - |> lib.filter (host: host.config.custom.services.private-nameserver.enable) - |> lib.map (host: host.config.custom.networking.overlay.address); + |> lib.filter (host: host.config.custom.services.recursive-nameserver.enable) + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}:${toString host.config.custom.services.recursive-nameserver.port}" + ); }; implementation = lib.mkOption { diff --git a/modules/nixos/services/nameservers/private.nix b/modules/nixos/services/nameservers/private.nix index b19982e..e790be2 100644 --- a/modules/nixos/services/nameservers/private.nix +++ b/modules/nixos/services/nameservers/private.nix @@ -58,18 +58,24 @@ let }; in { - options.custom.services.private-nameserver.enable = lib.mkEnableOption ""; + options.custom.services.private-nameserver = { + enable = lib.mkEnableOption ""; + port = lib.mkOption { + type = lib.types.port; + default = 5335; + }; + }; config = lib.mkIf cfg.enable { services = { nsd = { enable = true; - interfaces = [ netCfg.overlay.interface ]; + interfaces = [ "${netCfg.overlay.address}@${toString cfg.port}" ]; zones.${netCfg.overlay.domain}.data = zoneData; }; nebula.networks.mesh.firewall.inbound = lib.singleton { - port = 53; + inherit (cfg) port; proto = "any"; host = "any"; }; diff --git a/modules/nixos/services/nameservers/public.nix b/modules/nixos/services/nameservers/public.nix index 79dbd6d..702c4e4 100644 --- a/modules/nixos/services/nameservers/public.nix +++ b/modules/nixos/services/nameservers/public.nix @@ -66,6 +66,10 @@ in { options.custom.services.public-nameserver = { enable = lib.mkEnableOption ""; + port = lib.mkOption { + type = lib.types.port; + default = 53; + }; zones = lib.mkOption { type = lib.types.nonEmptyListOf lib.types.nonEmptyStr; default = [ ]; @@ -73,14 +77,9 @@ in }; config = lib.mkIf cfg.enable { - networking.firewall = { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ 53 ]; - }; - services.nsd = { enable = true; - interfaces = [ netCfg.underlay.interface ]; + interfaces = [ "${netCfg.underlay.address}@${toString cfg.port}" ]; zones = cfg.zones |> lib.map (zone: { @@ -89,5 +88,10 @@ in }) |> lib.listToAttrs; }; + + networking.firewall = { + allowedTCPPorts = [ cfg.port ]; + allowedUDPPorts = [ cfg.port ]; + }; }; } diff --git a/modules/nixos/services/nameservers/recursive.nix b/modules/nixos/services/nameservers/recursive.nix new file mode 100644 index 0000000..dd807a0 --- /dev/null +++ b/modules/nixos/services/nameservers/recursive.nix @@ -0,0 +1,70 @@ +{ + config, + lib, + allHosts, + ... +}: +let + cfg = config.custom.services.recursive-nameserver; + netCfg = config.custom.networking; + + privateNameservers = + allHosts + |> lib.attrValues + |> lib.filter (host: host.config.custom.services.private-nameserver.enable); +in +{ + options.custom.services.recursive-nameserver = { + enable = lib.mkEnableOption ""; + port = lib.mkOption { + type = lib.types.port; + default = 53; + }; + }; + + config = lib.mkIf cfg.enable ( + lib.mkMerge [ + { + services = { + unbound = { + enable = true; + settings.server = { + interface = [ "${netCfg.overlay.address}@${toString cfg.port}" ]; + access-control = [ "${toString netCfg.overlay.networkCidr} allow" ]; + }; + }; + + nebula.networks.mesh.firewall.inbound = lib.singleton { + inherit (cfg) port; + proto = "any"; + host = "any"; + }; + }; + + systemd.services.unbound = { + requires = [ netCfg.overlay.systemdUnit ]; + after = [ netCfg.overlay.systemdUnit ]; + }; + } + + (lib.mkIf (privateNameservers != [ ]) { + services.unbound.settings = { + server = { + local-zone = ''"${netCfg.overlay.domain}." nodefault''; + domain-insecure = netCfg.overlay.domain; + }; + + stub-zone = lib.singleton { + name = netCfg.overlay.domain; + stub-addr = + privateNameservers + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}@${toString host.config.custom.services.private-nameserver.port}" + ); + }; + }; + }) + ] + ); +} diff --git a/tests/infrastructure/default.nix b/tests/infrastructure/default.nix index 0838d71..a79e9c8 100644 --- a/tests/infrastructure/default.nix +++ b/tests/infrastructure/default.nix @@ -58,7 +58,10 @@ }; }; - services.private-nameserver.enable = true; + services = { + recursive-nameserver.enable = true; + private-nameserver.enable = true; + }; }; }; @@ -133,7 +136,7 @@ client1.wait_for_unit("${client1NetCfg.overlay.systemdUnit}") client2.wait_for_unit("${client2NetCfg.overlay.systemdUnit}") - lighthouse.wait_for_unit("nsd.service") + lighthouse.wait_for_unit("unbound.service") lighthouse.wait_for_open_port(53, "${lighthouseNetCfg.overlay.address}") server.wait_for_unit("sshd.service")