{ config, inputs, lib, this, ... }: with lib; let cfg = config.nixfiles.modules.nsd; in { options.nixfiles.modules.nsd = { enable = mkEnableOption "NSD"; fqdn = mkOption { description = "FQDN of this nameserver."; type = with types; str; default = "ns.${config.networking.domain}"; }; }; config = mkIf cfg.enable { services = { nsd = { enable = true; interfaces = with this; [ipv4.address ipv6.address]; ipTransparent = true; ratelimit.enable = true; zones = let dns = inputs.dns-nix.lib; in with dns.combinators; let ips = hostname: with my.configurations.${hostname}; { A = [(a ipv4.address)]; AAAA = [(aaaa ipv6.address)]; }; mkEmailEntries = { domain ? my.domain.shire, dkimKey ? null, }: { MX = [(mx.mx 10 "${domain}.")]; TXT = [(spf.strict ["a" "mx"])]; DMARC = [ { p = "quarantine"; sp = "quarantine"; rua = ["mailto:admin+rua@${domain}"]; ruf = ["mailto:admin+ruf@${domain}"]; } ]; DKIM = optional (dkimKey != null) { selector = "mail"; p = dkimKey; }; }; mkZone = { domain, sldIps ? (ips "manwe"), extra ? {}, }: { ${domain}.data = dns.toString domain (mkMerge [ { TTL = 60 * 60; SOA = { nameServer = "${cfg.fqdn}."; adminEmail = "admin+dns@${my.domain.shire}"; serial = 2022091601; # Don't forget to bump the revision! }; NS = with my.domain; [ "ns1.${shire}" # "ns2.${shire}" ]; CAA = letsEncrypt "admin+caa@${my.domain.shire}"; } sldIps extra ]); }; # https://ariadne.id/ # https://docs.keyoxide.org/service-providers/dns/ ariadneIdProof.TXT = ["openpgp4fpr:${my.pgp.fingerprint}"]; in mkMerge [ (mkZone { domain = my.domain.shire; extra = mkMerge [ (mkEmailEntries { dkimKey = "@DKIM_KEY@"; }) { subdomains = rec { manwe = ips "manwe"; "*.manwe" = manwe; varda = ips "varda"; "*.varda" = varda; yavanna = ips "yavanna"; "*.yavanna" = yavanna; ns1 = manwe; # ns2 = varda; alertmanager = manwe; bitwarden = manwe; git = manwe; gotify = manwe; grafana = manwe; loki = manwe; prometheus = manwe; radicale = manwe; rss-bridge = manwe; vaultwarden = manwe; minecraft = varda; flood = yavanna; }; } ]; }) (mkZone { domain = my.domain.azahi; extra = mkMerge [ (mkEmailEntries { dkimKey = "@DKIM_KEY@"; }) ariadneIdProof { subdomains.git = ips "manwe"; } ]; }) (mkZone { domain = my.domain.gondor; extra = mkMerge [ (mkEmailEntries { dkimKey = "@DKIM_KEY@"; }) { subdomains.frodo = ips "manwe" // ariadneIdProof; } ]; }) (mkZone { domain = my.domain.rohan; extra = mkMerge [ (mkEmailEntries { dkimKey = "@DKIM_KEY@"; }) { subdomains.frodo = ips "manwe" // ariadneIdProof; } ]; }) ]; }; fail2ban.jails.nsd = '' enabled = true ''; }; networking.firewall = rec { allowedTCPPorts = [53]; allowedUDPPorts = allowedTCPPorts; }; }; }