{ self, pkgs, lib, config, dns, ... }: let secondary = "185.181.104.96"; domain = config.networking.domain; zonefile = with dns.lib.combinators; pkgs.writeText "rfive.de.zone.txt" (dns.lib.toString domain { TTL = 3600; SOA = let modulo = number: mod: (number - ((number / mod) * mod)); in { nameServer = "ns.rfive.de."; adminEmail = "hostmaster@rfive.de"; serial = lib.strings.toInt (builtins.substring 0 8 self.sourceInfo.lastModifiedDate + toString ((modulo self.sourceInfo.lastModified 86400) / 864)); refresh = 10800; retry = 3600; expire = 604800; minimum = 3600; }; NS = [ "ns.inwx.de." "ns2.inwx.de." "ns3.inxw.eu." ]; A = [ "23.88.121.184" ]; AAAA = [ "2a01:4f8:c012:49de::1" ]; CAA = letsEncrypt "ca@rfive.de"; MX = [{ preference = 1; exchange = "mail.rfive.de."; }]; TXT = [ (spf.soft [ "mx" ]) ]; subdomains = let getVirtualHosts = hostname: map (name: builtins.substring 0 (builtins.stringLength name - (builtins.stringLength domain + 1)) name) (builtins.attrNames self.nixosConfigurations."${hostname}".config.services.caddy.virtualHosts); genCNAMEs = hostname: lib.attrsets.genAttrs (getVirtualHosts hostname) (label: { CNAME = [ "${hostname}.${domain}." ]; }); in lib.attrsets.mergeAttrsList [ rec { nuc = { A = [ "141.30.227.6" ]; }; falkenstein = { A = [ "23.88.121.184" ]; AAAA = [ "2a01:4f8:c012:49de::1" ]; }; ns = falkenstein; mail = falkenstein; _dmarc.TXT = [ "v=DMARC1; p=none; adkim=s; fo=1; rua=mailto:dmarc@rfive.de; ruf=mailto:dmarc@rfive.de" ]; _domainkey.subdomains.rspamd.TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoirUMubro4nlmY6a8JMwK9QB2agAXiJzexDU/7ba6KCggONfoSTfUHlrM/XeM1GG/9oKpngApxDPP97adJuxc8/EELyo4HjTyYD8GBFZhg0AN7V8IPaJ1o5k6dGDk8ZLh41ZCnlAVWkhVSKs5pYtzkrlJIfUSzyuoe8nuFsVe3QIDAQAB" ]; } (builtins.removeAttrs (genCNAMEs "nuc") [ ":2018" ]) (builtins.removeAttrs (genCNAMEs "falkenstein") [ "mail" ":2018" ]) ]; }); in { services.bind = rec { enable = true; directory = "/var/lib/bind"; extraConfig = '' dnssec-policy "split-keys" { keys { ksk lifetime unlimited algorithm ecdsap256sha256; zsk lifetime 60d algorithm ecdsap256sha256; }; publish-safety 1d; retire-safety 1d; }; ''; zones = { "rfive.de" = { master = true; slaves = [ secondary ]; extraConfig = '' also-notify {${secondary};}; dnssec-policy split-keys; inline-signing yes; serial-update-method date; ''; file = "${directory}/rfive.de.zone.txt"; }; }; }; systemd.services.bind.preStart = '' # copy the file manually to its destination since signing requires a writable directory ${pkgs.coreutils}/bin/cp ${zonefile} ${config.services.bind.directory}/rfive.de.zone.txt ${pkgs.coreutils}/bin/chown named:named ${config.services.bind.directory}/rfive.de.zone.txt ''; networking.firewall.extraInputRules = '' ip saddr ${secondary}/32 tcp dport 53 accept comment "Allow DNS AXFR access from INWX Servers" ip saddr ${secondary}/32 udp dport 53 accept comment "Allow DNS access from INWX Servers" ''; environment.systemPackages = with pkgs; [ dig.out ]; }