dns: switch to knot
This commit is contained in:
parent
d7fdfd8aa6
commit
9b2b8250c4
|
@ -5,7 +5,7 @@ let
|
|||
|
||||
generateZoneFile = let
|
||||
util = dns-nix.util.${pkgs.system};
|
||||
in { name, ns, records, ... }: util.writeZone name (with dns-nix.lib.combinators; {
|
||||
in { name, ns, records, ... }: util.writeZone name {
|
||||
TTL = 60*60;
|
||||
SOA = {
|
||||
nameServer = "${lib.dns.ns}.";
|
||||
|
@ -20,7 +20,7 @@ let
|
|||
subdomains = lib.foldl (a: b: lib.recursiveUpdate a b) { } (map ({ name, type, data }: {
|
||||
${name}.${type} = [ data ];
|
||||
}) records);
|
||||
});
|
||||
};
|
||||
in
|
||||
{
|
||||
options =
|
||||
|
@ -69,108 +69,163 @@ in
|
|||
config = {
|
||||
site.dns.localZones = lib.dns.localZones;
|
||||
|
||||
services.bind = lib.mkIf config.site.hosts.${hostName}.services.dns.enable (
|
||||
services.knot = lib.mkIf config.site.hosts.${hostName}.services.dns.enable (
|
||||
let
|
||||
generateZone = zone@{ name, dynamic, ... }: {
|
||||
inherit name;
|
||||
master = true;
|
||||
# allowed for zone-transfer
|
||||
slaves = [
|
||||
# ns.c3d2.de
|
||||
"217.197.84.53" "2001:67c:1400:2240::a"
|
||||
config.site.net.serv.hosts4.knot
|
||||
config.site.net.serv.hosts6.dn42.knot
|
||||
config.site.net.serv.hosts6.up4.knot
|
||||
# ns.spaceboyz.net
|
||||
"172.22.24.4" "2a01:4f9:4b:39ec::4"
|
||||
# ns1.supersandro.de
|
||||
"188.34.196.104" "2a01:4f8:1c1c:1d38::1"
|
||||
];
|
||||
file =
|
||||
if dynamic
|
||||
then "/var/db/bind/${name}.zone"
|
||||
domain = name;
|
||||
template = "zentralwerk";
|
||||
acl = [ "zone_xfr" ] ++ lib.optional dynamic "dyndns";
|
||||
file = if dynamic
|
||||
then "/var/lib/knot/zones/${name}.zone"
|
||||
else generateZoneFile zone;
|
||||
extraConfig = ''
|
||||
also-notify {
|
||||
# ns.c3d2.de
|
||||
217.197.84.53;
|
||||
2001:67c:1400:2240::a;
|
||||
${config.site.net.serv.hosts4.knot};
|
||||
${config.site.net.serv.hosts6.dn42.knot};
|
||||
${config.site.net.serv.hosts6.up4.knot};
|
||||
# ns.spaceboyz.net
|
||||
172.22.24.4;
|
||||
95.217.229.209;
|
||||
2a01:4f9:4b:39ec::4;
|
||||
# ns1.supersandro.de
|
||||
188.34.196.104;
|
||||
2a01:4f8:1c1c:1d38::1;
|
||||
};
|
||||
notify-source ${config.site.net.serv.hosts4.dns};
|
||||
notify-source-v6 ${config.site.net.serv.hosts6.up4.dns};
|
||||
'' + lib.optionalString dynamic ''
|
||||
allow-update { key "dyndns"; };
|
||||
'';
|
||||
notify = [ "all" ];
|
||||
};
|
||||
|
||||
in {
|
||||
enable = true;
|
||||
zones = map generateZone config.site.dns.localZones;
|
||||
settings = {
|
||||
acl = [
|
||||
{
|
||||
id = "dyndns";
|
||||
action = "update";
|
||||
}
|
||||
{
|
||||
id = "zone_xfr";
|
||||
address = with config.site.net.serv; [
|
||||
# ns.c3d2.de
|
||||
hosts4.knot hosts6.dn42.knot hosts6.up4.knot
|
||||
# ns.spaceboyz.net
|
||||
"172.22.24.4" "2a01:4f9:4b:39ec::4"
|
||||
# ns1.supersandro.de
|
||||
"188.34.196.104" "2a01:4f8:1c1c:1d38::1"
|
||||
];
|
||||
action = "transfer";
|
||||
}
|
||||
];
|
||||
|
||||
extraConfig = ''
|
||||
key "dyndns" {
|
||||
algorithm hmac-sha256;
|
||||
secret "${config.site.dyndnsKey}";
|
||||
key = [ {
|
||||
id = "dyndns";
|
||||
algorithm = "hmac-sha256";
|
||||
secret = config.site.dyndnsKey;
|
||||
} ];
|
||||
|
||||
log = [ {
|
||||
target = "syslog";
|
||||
any = "info";
|
||||
} ];
|
||||
|
||||
mod-stats = [ {
|
||||
id = "default";
|
||||
query-type = "on";
|
||||
} ];
|
||||
|
||||
remote = let
|
||||
via = with config.site.net.serv; [ hosts4.dns hosts6.up4.dns ];
|
||||
in [
|
||||
{
|
||||
id = "ns.c3d2.de";
|
||||
address = with config.site.net.serv; [ hosts4.knot hosts6.dn42.knot hosts6.up4.knot ];
|
||||
inherit via;
|
||||
} {
|
||||
id = "ns.spaceboyz.net";
|
||||
address = [ "172.22.24.4" "2a01:4f9:4b:39ec::4" ];
|
||||
inherit via;
|
||||
} {
|
||||
id = "ns1.supersandro.de";
|
||||
address = [ "188.34.196.104" "2a01:4f8:1c1c:1d38::1" ];
|
||||
inherit via;
|
||||
}
|
||||
];
|
||||
|
||||
remotes = [ {
|
||||
id = "all";
|
||||
remote = [ "ns.c3d2.de" "ns.spaceboyz.net" "ns1.supersandro.de" ];
|
||||
} ];
|
||||
|
||||
server = {
|
||||
answer-rotation = true;
|
||||
automatic-acl = true;
|
||||
identity = "dns.serv.zentralwerk.org";
|
||||
tcp-fastopen = true;
|
||||
version = null;
|
||||
};
|
||||
'';
|
||||
extraOptions = ''
|
||||
# allow underscores in dynamic hostnames
|
||||
${lib.concatMapStringsSep "\n" (type: ''
|
||||
check-names ${type} ignore;
|
||||
'') [ "master" "slave" "response" ]}
|
||||
'';
|
||||
|
||||
template = [
|
||||
{
|
||||
# default is a magic name and is always loaded.
|
||||
# Because we want to use catalog-role/catalog-zone settings for all zones *except* the catalog zone itself, we must split the templates
|
||||
id = "default";
|
||||
global-module = [ "mod-stats" ];
|
||||
}
|
||||
{
|
||||
id = "zentralwerk";
|
||||
catalog-role = "member";
|
||||
catalog-zone = "zentralwerk.";
|
||||
dnssec-signing = true;
|
||||
journal-content = "all"; # required for zonefile-load=difference-no-serial and makes cold starts like zone reloads
|
||||
module = "mod-stats/default";
|
||||
semantic-checks = true;
|
||||
serial-policy = "dateserial";
|
||||
storage = "/var/lib/knot/zones";
|
||||
zonefile-load = "difference-no-serial";
|
||||
}
|
||||
];
|
||||
|
||||
zone = [
|
||||
{
|
||||
acl = "zone_xfr";
|
||||
catalog-role = "generate";
|
||||
domain = "zentralwerk.";
|
||||
notify = [ "ns1.supersandro.de" ];
|
||||
storage = "/var/lib/knot/catalog";
|
||||
}
|
||||
] ++ map generateZone config.site.dns.localZones;
|
||||
};
|
||||
});
|
||||
|
||||
systemd.services.create-dynamic-zones = {
|
||||
description = "Creates dynamic zone files";
|
||||
requiredBy = [ "bind.service" ];
|
||||
before = [ "bind.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/db/bind
|
||||
systemd.services = {
|
||||
create-dynamic-zones = {
|
||||
description = "Creates dynamic zone files";
|
||||
requiredBy = [ "knot.service" ];
|
||||
before = [ "knot.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/lib/knot/zones
|
||||
|
||||
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
||||
[ -e /var/db/bind/${name}.zone ] || \
|
||||
cp ${generateZoneFile zone} /var/db/bind/${name}.zone
|
||||
chown -R named /var/db/bind
|
||||
chmod -R u+rwX /var/db/bind
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
};
|
||||
systemd.services.update-dynamic-zones = {
|
||||
description = "Creates initial records in dynamic zone files";
|
||||
requiredBy = [ "bind.service" ];
|
||||
after = [ "bind.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.dnsutils ];
|
||||
script = ''
|
||||
${lib.concatMapStrings (zone: ''
|
||||
nsupdate -v -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
||||
server localhost
|
||||
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
||||
[ -e /var/lib/knot/zones/${name}.zone ] || \
|
||||
cp ${generateZoneFile zone} /var/lib/knot/zones/${name}.zone
|
||||
chown -R knot /var/lib/knot/zones
|
||||
chmod -R u+rwX /var/lib/knot/zones
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
};
|
||||
|
||||
${lib.concatMapStringsSep "\n" ({ name, type, data }: ''
|
||||
delete ${name}.${zone.name}. IN ${type}
|
||||
add ${name}.${zone.name}. 3600 IN ${type} ${data}
|
||||
'') zone.records}
|
||||
update-dynamic-zones = {
|
||||
description = "Creates initial records in dynamic zone files";
|
||||
requiredBy = [ "knot.service" ];
|
||||
after = [ "knot.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.dnsutils ];
|
||||
script = ''
|
||||
${lib.concatMapStrings (zone: ''
|
||||
nsupdate -v -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
||||
server localhost
|
||||
|
||||
send
|
||||
EOF
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
${lib.concatMapStringsSep "\n" ({ name, type, data }: ''
|
||||
delete ${name}.${zone.name}. IN ${type}
|
||||
add ${name}.${zone.name}. 3600 IN ${type} ${data}
|
||||
'') zone.records}
|
||||
|
||||
send
|
||||
EOF
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue