summaryrefslogtreecommitdiff
path: root/sys/ns/ns.nix
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2025-04-19 10:48:15 -0600
committerAlejandro Soto <alejandro@34project.org>2025-04-24 14:27:38 -0600
commit1039d1d47a53be0c814a03608e94a9d0e8f4405b (patch)
treea6cf802896f0ad41742354499df8063d9065eb02 /sys/ns/ns.nix
parentf4ed93ff7d01e659960b9cd3dc5bc3d6d6e27d01 (diff)
sys/ns: implement automatic PTR zones
Diffstat (limited to 'sys/ns/ns.nix')
-rw-r--r--sys/ns/ns.nix152
1 files changed, 108 insertions, 44 deletions
diff --git a/sys/ns/ns.nix b/sys/ns/ns.nix
index 4c242b6..a1b1605 100644
--- a/sys/ns/ns.nix
+++ b/sys/ns/ns.nix
@@ -1,54 +1,118 @@
{ config, lib, ... }:
with lib; let
- inherit (config.local.ns.server) tsigName;
+ inherit (config.networking) domain;
inherit (config.local.nets) gate-public;
+ inherit (config.local.ns.server) tsigName;
+
+ ptrNets = config.local.ns.ptr;
in
{
options.local.ns.zones = mkOption {
- type = with lib.types; attrsOf (submodule ({ config, name, ... }:
- let
- cfg = config.localNS;
- in
- {
- options.localNS = {
- enable = mkEnableOption "local NS settings";
-
- primary = mkOption {
- type = str;
- default = "ns1";
- };
- };
-
- config = mkIf cfg.enable {
- # https://docs.gandi.net/en/domain_names/advanced_users/secondary_nameserver.html
- nsdConfig =
- let
- providerSecondary = [
- "37.205.15.45 ${tsigName}" # ns3.vpsfree.cz
- "37.205.11.85 ${tsigName}" # ns4.vpsfree.cz
- "2a03:3b40:fe:2be::1 ${tsigName}" # ns3.vpsfree.cz
- "2a03:3b40:101:4::1 ${tsigName}" # ns4.vpsfree.cz
- ];
- in
- {
- notify = providerSecondary;
- provideXFR = providerSecondary;
+ type = with lib.types; attrsOf
+ (submodule
+ ({ config, name, ... }:
+ let
+ inherit (config.soa) primary;
+
+ cfg = config.localNS;
+ ptrDomain = cfg.ptrNet.v4 != null || cfg.ptrNet.v6 != null;
+ in
+ {
+ options.localNS = {
+ enable = mkEnableOption "local NS settings";
+
+ ptrNet = {
+ v4 = mkOption {
+ type = nullOr str;
+ default = null;
+ };
+
+ v6 = mkOption {
+ type = nullOr str;
+ default = null;
+ };
+ };
};
- ns = [
- { name = "@"; host = cfg.primary; }
- { name = "@"; host = "ns3.vpsfree.cz."; }
- { name = "@"; host = "ns4.vpsfree.cz."; }
- ];
-
- a = [
- { name = cfg.primary; ipv4 = gate-public.hosts.gate.v4.address; }
- ];
-
- aaaa = [
- { name = cfg.primary; ipv6 = gate-public.hosts.gate.v6.address; }
- ];
- };
- }));
+ config = mkIf cfg.enable
+ {
+ ptrName =
+ let
+ name =
+ if cfg.ptrNet.v6 != null
+ then "${cfg.ptrNet.v6}-v6"
+ else "${cfg.ptrNet.v4}-v4";
+ in
+ mkIf ptrDomain name;
+
+ # https://docs.gandi.net/en/domain_names/advanced_users/secondary_nameserver.html
+ nsdConfig =
+ let
+ providerSecondary = [
+ "37.205.15.45 ${tsigName}" # ns3.vpsfree.cz
+ "37.205.11.85 ${tsigName}" # ns4.vpsfree.cz
+ "2a03:3b40:fe:2be::1 ${tsigName}" # ns3.vpsfree.cz
+ "2a03:3b40:101:4::1 ${tsigName}" # ns4.vpsfree.cz
+ ];
+ in
+ {
+ notify = providerSecondary;
+ provideXFR = providerSecondary;
+ };
+
+ ns = [
+ { name = "@"; host = primary; }
+ { name = "@"; host = "ns3.vpsfree.cz."; }
+ { name = "@"; host = "ns4.vpsfree.cz."; }
+ ];
+
+ a = optional (!ptrDomain)
+ { name = primary; ipv4 = gate-public.hosts.gate.v4.address; ptr = null; };
+
+ aaaa = optional (!ptrDomain)
+ { name = primary; ipv6 = gate-public.hosts.gate.v6.address; ptr = null; };
+
+ ptr =
+ let
+ ptrsToRecords = mapAttrsToList (suffix: target: {
+ name = suffix;
+ inherit target;
+ });
+
+ v4Net = cfg.ptrNet.v4;
+ v6Net = cfg.ptrNet.v6;
+
+ v4Records = optionals (v4Net != null) (ptrsToRecords ptrNets.${v4Net}.v4.targets);
+ v6Records = optionals (v6Net != null) (ptrsToRecords ptrNets.${v6Net}.v6.targets);
+ in
+ v4Records ++ v6Records;
+
+ soa = mkIf ptrDomain {
+ authorityZone = mkDefault "${domain}.";
+ };
+ };
+ }));
};
+
+ config =
+ {
+ assertions = mapAttrsToList
+ (name: zone: {
+ assertion = zone.localNS.ptrNet.v4 != null -> zone.localNS.ptrNet.v6 == null;
+ message = "zone '${name}' defined as both a v4 and v6 PTR zone";
+ })
+ config.local.ns.zones;
+
+ local.ns.ptr =
+ let
+ zonePtrNets = name: zone:
+ optionalAttrs (zone.localNS.ptrNet.v4 != null)
+ {
+ ${zone.localNS.ptrNet.v4}.v4.zone = name;
+ } // optionalAttrs (zone.localNS.ptrNet.v6 != null) {
+ ${zone.localNS.ptrNet.v6}.v6.zone = name;
+ };
+ in
+ mkMerge (flatten (mapAttrsToList zonePtrNets (filterAttrs (_: zone: zone.localNS.enable) config.local.ns.zones)));
+ };
}