authoritative-dns/reverse-zone.nix

75 lines
2.4 KiB
Nix
Raw Normal View History

2023-11-01 10:13:33 -07:00
{ pkgs, ... }:
2023-11-09 10:08:32 -08:00
{ domain, network, nameservers, notify, ipHostMap, serial, keyFile ? null
2023-11-03 13:10:50 -07:00
, zoneTTL ? 10800, refresh ? 3600, retry ? 1800, expire ? 604800, minimum ? 3600
}:
2023-11-01 10:13:33 -07:00
with pkgs.lib;
let
2023-11-17 09:19:30 -08:00
inherit (pkgs.lib.fudo.ip)
2023-11-03 18:15:24 -07:00
networkMinIp networkMaxIp ipv4OnNetwork getNetworkMask getNetworkBase;
2023-11-03 11:01:14 -07:00
2023-11-01 10:13:33 -07:00
range = base: top:
assert base < top;
let
rangeFun = base: top:
2023-11-04 14:29:41 -07:00
if base == top then [ base ] else [ base ] ++ (rangeFun (base + 1) top);
2023-11-01 10:13:33 -07:00
in rangeFun base top;
2023-11-03 12:53:57 -07:00
getNetworkHosts = network: filterAttrs (ip: _: ipv4OnNetwork ip network);
2023-11-01 10:13:33 -07:00
getLastIpComponent = ip: head (reverseList (splitString "." ip));
getNetworkZoneName = network:
let
netElems = splitString "/" network;
2023-11-03 13:35:36 -07:00
netIp = getNetworkBase network;
netMask = getNetworkMask network;
2023-11-01 10:13:33 -07:00
reversedNetIp =
concatStringsSep "." (tail (reverseList (splitString "." netIp)));
2023-11-03 13:37:05 -07:00
in if netMask == 24 then
2023-11-01 10:13:33 -07:00
"${reversedNetIp}.in-addr.arpa."
else
2023-11-03 13:37:05 -07:00
"${getLastIpComponent netIp}-${
toString netMask
}.${reversedNetIp}.in-addr.arpa.";
2023-11-01 10:13:33 -07:00
generateReverseZoneEntries = network: domain: ipHostMap:
let
networkHostsByComponent =
mapAttrs' (ip: hostname: nameValuePair (getLastIpComponent ip) hostname)
2023-11-03 11:03:48 -07:00
(getNetworkHosts network ipHostMap);
2023-11-03 13:24:08 -07:00
ptrEntry = ip: hostname: "${toString ip} IN PTR ${hostname}.";
2023-11-01 10:13:33 -07:00
getHostname = n:
2023-11-03 12:53:57 -07:00
if hasAttr n networkHostsByComponent then
2023-11-03 12:55:52 -07:00
networkHostsByComponent."${n}"
2023-11-01 10:13:33 -07:00
else
"unassigned-${n}.${domain}";
minIp = toInt (getLastIpComponent (networkMinIp network));
2023-11-03 18:15:24 -07:00
maxIp = toInt (getLastIpComponent (networkMaxIp network));
2023-11-01 10:13:33 -07:00
in map (n: ptrEntry n (getHostname (toString n))) (range minIp maxIp);
2023-11-03 13:33:38 -07:00
nameserverEntries = map (nameserver: "@ IN NS ${nameserver}") nameservers;
2023-11-01 10:13:33 -07:00
2023-11-03 13:10:50 -07:00
in nameValuePair "${getNetworkZoneName network}" {
dnssec = keyFile != null;
ksk.keyFile = keyFile;
2023-11-09 10:08:32 -08:00
provideXFR = (map (ns: "${ns}/32 NOKEY") notify.ipv4)
++ (map (ns: "${ns}/64 NOKEY") notify.ipv6);
notify = map (ns: "${ns} NOKEY") (notify.ipv4 ++ notify.ipv6);
2023-11-03 13:10:50 -07:00
data = ''
$ORIGIN ${getNetworkZoneName network}
$TTL ${toString zoneTTL}
2023-11-03 13:33:38 -07:00
@ IN SOA ${head nameservers} hostmaster.${domain}. (
2023-11-03 13:10:50 -07:00
${serial}
${toString refresh}
${toString retry}
${toString expire}
${toString minimum}
)
${concatStringsSep "\n" nameserverEntries}
${concatStringsSep "\n"
(generateReverseZoneEntries network domain ipHostMap)}
'';
}