Initial attempt at reverse zones
This commit is contained in:
parent
d3272846b4
commit
793be43cc2
|
@ -8,6 +8,8 @@ let
|
||||||
|
|
||||||
zoneToZonefile = import ./zone-to-zonefile.nix { inherit lib; };
|
zoneToZonefile = import ./zone-to-zonefile.nix { inherit lib; };
|
||||||
|
|
||||||
|
reverseZonefile = import ./reverse-zone.nix { inherit pkgs; };
|
||||||
|
|
||||||
domainOpts = { name, ... }: {
|
domainOpts = { name, ... }: {
|
||||||
options = with types; {
|
options = with types; {
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
|
@ -29,6 +31,13 @@ let
|
||||||
type = submodule zoneOpts;
|
type = submodule zoneOpts;
|
||||||
description = "Definition of network zone to be served.";
|
description = "Definition of network zone to be served.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reverse-zones = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of subnets for which to generate reverse lookup zones.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,17 +83,27 @@ in {
|
||||||
identity = cfg.identity;
|
identity = cfg.identity;
|
||||||
interfaces = cfg.listen-ips;
|
interfaces = cfg.listen-ips;
|
||||||
stateDirectory = cfg.state-directory;
|
stateDirectory = cfg.state-directory;
|
||||||
zones = mapAttrs' (domain: domainCfg:
|
zones = let
|
||||||
nameValuePair "${domain}." {
|
forwardZones = mapAttrs' (domain: domainCfg:
|
||||||
dnssec = domainCfg.ksk.key-file != null;
|
nameValuePair "${domain}." {
|
||||||
ksk.keyFile =
|
dnssec = domainCfg.ksk.key-file != null;
|
||||||
mkIf (domainCfg.ksk.key-file != null) domainCfg.ksk.key-file;
|
ksk.keyFile =
|
||||||
data = zoneToZonefile {
|
mkIf (domainCfg.ksk.key-file != null) domainCfg.ksk.key-file;
|
||||||
inherit domain;
|
data = zoneToZonefile {
|
||||||
inherit (cfg) timestamp;
|
inherit domain;
|
||||||
inherit (domainCfg) zone;
|
inherit (cfg) timestamp;
|
||||||
};
|
inherit (domainCfg) zone;
|
||||||
}) cfg.domains;
|
};
|
||||||
|
}) cfg.domains;
|
||||||
|
reverseZones = concatMapAttrs (domain: domainOpts:
|
||||||
|
genAttrs domainOpts.reverse-zones (network:
|
||||||
|
reverseZonefile {
|
||||||
|
inherit domain network;
|
||||||
|
inherit (domainOpts.zone) nameservers;
|
||||||
|
ipHostMap = cfg.ip-host-map;
|
||||||
|
serial = cfg.timestamp;
|
||||||
|
})) cfg.domains;
|
||||||
|
in forwardZones // reverseZones;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{ domain, network, nameservers, ipHostMap, serial, zoneTTL ? 10800
|
||||||
|
, refresh ? 3600, retry ? 1800, expire ? 604800, minimum ? 3600 }:
|
||||||
|
|
||||||
|
with pkgs.lib;
|
||||||
|
let
|
||||||
|
range = base: top:
|
||||||
|
assert base < top;
|
||||||
|
let
|
||||||
|
rangeFun = base: top:
|
||||||
|
if base == top then [ ] else [ base ] ++ (rangeFun (base + 1) top);
|
||||||
|
in rangeFun base top;
|
||||||
|
|
||||||
|
getNetworkHosts = network:
|
||||||
|
selectAttrs (ip: _: pkgs.lib.ip.ipv4OnNetwork ip network);
|
||||||
|
|
||||||
|
getLastIpComponent = ip: head (reverseList (splitString "." ip));
|
||||||
|
|
||||||
|
getNetworkZoneName = network:
|
||||||
|
let
|
||||||
|
netElems = splitString "/" network;
|
||||||
|
netIp = elemAt netElems 0;
|
||||||
|
netMask = elemAt netElems 1;
|
||||||
|
reversedNetIp =
|
||||||
|
concatStringsSep "." (tail (reverseList (splitString "." netIp)));
|
||||||
|
in if netMask == "24" then
|
||||||
|
"${reversedNetIp}.in-addr.arpa."
|
||||||
|
else
|
||||||
|
"${getLastIpComponent netIp}-${netMask}.${reversedNetIp}.in-addr.arpa.";
|
||||||
|
|
||||||
|
generateReverseZoneEntries = network: domain: ipHostMap:
|
||||||
|
let
|
||||||
|
networkHostsByComponent =
|
||||||
|
mapAttrs' (ip: hostname: nameValuePair (getLastIpComponent ip) hostname)
|
||||||
|
(networkHosts network ipHostMap);
|
||||||
|
ptrEntry = ip: hostname: "#{ip} IN PTR ${hostname}.";
|
||||||
|
getHostname = n:
|
||||||
|
if hasAttr networkHostsByComponent n then
|
||||||
|
networkHostByComponent n
|
||||||
|
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);
|
||||||
|
|
||||||
|
nameserverEntries = map (nameserver: "@ IN NS ${nameserver}.") nameservers;
|
||||||
|
|
||||||
|
in nameValuePair "${getNetworkZoneName network}" ''
|
||||||
|
$ORIGIN ${getNetworkZoneName network}
|
||||||
|
$TTL ${toString zoneTTL}
|
||||||
|
@ IN SOA ${head nameservers}. hostmaster.${domain}. (
|
||||||
|
${serial}
|
||||||
|
${toString refresh}
|
||||||
|
${toString retry}
|
||||||
|
${toString expire}
|
||||||
|
${toString minimum}
|
||||||
|
)
|
||||||
|
${concatStringsSep "\n" nameserverEntries}
|
||||||
|
${concatStringsSep "\n" (generateReverseZoneEntries network domain ipHostMap)}
|
||||||
|
''
|
Loading…
Reference in New Issue