2023-11-01 10:13:33 -07:00
|
|
|
{ pkgs, ... }:
|
|
|
|
|
2023-11-03 13:10:50 -07:00
|
|
|
{ domain, network, nameservers, ipHostMap, serial, keyFile ? null
|
|
|
|
, zoneTTL ? 10800, refresh ? 3600, retry ? 1800, expire ? 604800, minimum ? 3600
|
|
|
|
}:
|
2023-11-01 10:13:33 -07:00
|
|
|
|
|
|
|
with pkgs.lib;
|
|
|
|
let
|
2023-11-03 13:35:36 -07:00
|
|
|
inherit (pkgs.lib.ip)
|
|
|
|
networkMinIp networkMaxButOneIp 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:
|
|
|
|
if base == top then [ ] else [ base ] ++ (rangeFun (base + 1) top);
|
|
|
|
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));
|
|
|
|
maxIp = toInt (getLastIpComponent (networkMaxButOneIp network));
|
|
|
|
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;
|
|
|
|
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)}
|
|
|
|
'';
|
|
|
|
}
|