about summary refs log tree commit diff
path: root/modules/nixos/nsd.nix
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2022-12-17 16:39:09 +0300
committerAzat Bahawi <azat@bahawi.net>2022-12-17 16:39:09 +0300
commit8f137c28230623259a964484adcf31fe00756594 (patch)
tree82bce6a13fda125087cf6d9dc80aa91d9230d6c4 /modules/nixos/nsd.nix
parent2022-11-20 (diff)
2022-12-17
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;
+    };
+  };
+}

Consider giving Nix/NixOS a try! <3