summaryrefslogtreecommitdiff
path: root/modules/nixos/nsd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/nixos/nsd.nix')
-rw-r--r--modules/nixos/nsd.nix174
1 files changed, 174 insertions, 0 deletions
diff --git a/modules/nixos/nsd.nix b/modules/nixos/nsd.nix
new file mode 100644
index 0000000..0dade8f
--- /dev/null
+++ b/modules/nixos/nsd.nix
@@ -0,0 +1,174 @@
+{
+ 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;
+ };
+ };
+}