mermet: nebula: sourcephile.fr: adapt to new conventions
[sourcephile-nix.git] / hosts / mermet / knot / sourcephile.fr.nix
index 2f908e674317a04b2965a7cfc77f7bf02534b4c9..6b788a1fc201457028fdb209ec270c28641972a2 100644 (file)
@@ -1,78 +1,21 @@
-{ pkgs, lib, config, inputs, hostName, hosts, info, ... }:
+{
+  pkgs,
+  lib,
+  config,
+  inputs,
+  hosts,
+  info,
+  ...
+}:
 let
   domain = "sourcephile.fr";
   domainID = lib.replaceStrings [ "." ] [ "_" ] domain;
   inherit (config) networking;
   inherit (config.services) knot;
-in
-{
-  services.knot.zones.${domain} = {
-    conf = ''
-      remote:
-        - id: ns_iodine
-          address: 127.0.0.1@1053
-      acl:
-        - id: acl_localhost_acme_${domainID}
-          address: 127.0.0.1
-          action: update
-          update-owner: name
-          update-owner-match: equal
-          update-owner-name: [_acme-challenge]
-          update-type: [TXT]
-        - id: acl_tsig_acme_${domainID}
-          key: acme_${domainID}
-          action: update
-          update-owner: name
-          update-owner-match: equal
-          update-owner-name: [_acme-challenge]
-          update-type: [TXT]
-        - id: acl_tsig_losurdo_${domainID}
-          key: losurdo_${domainID}
-          action: update
-          update-owner: name
-          update-owner-match: equal
-          update-owner-name: [losurdo, lan.losurdo]
-          update-type: [A, AAAA]
-
-      mod-dnsproxy:
-        - id: proxy_iodine
-          remote: ns_iodine
-          fallback: off
-
-      zone:
-        - domain: ${domain}
-          file: ${domain}.zone
-          serial-policy: increment
-          semantic-checks: on
-          notify: secondary_gandi
-          acl: acl_gandi
-          acl: acl_localhost_acme_${domainID}
-          acl: acl_tsig_acme_${domainID}
-          acl: acl_tsig_losurdo_${domainID}
-          dnssec-signing: on
-          dnssec-policy: rsa
-
-        #- domain: i.${domain}
-        #  module: mod-dnsproxy/proxy_iodine
-
-        - domain: whoami4.${domain}
-          module: mod-whoami
-          file: "${pkgs.writeText "whoami4.zone" ''
-            $TTL 1
-            @ SOA ns root.${domain}. (
-              0     ; SERIAL
-              86400 ; REFRESH
-              86400 ; RETRY
-              86400 ; EXPIRE
-              1 ; MINIMUM
-            )
-            $TTL 86400
-            @ NS ns
-            ns A ${hosts.mermet._module.args.ipv4}
-          ''}"
-    '';
+  inherit (config.users) users groups;
+  zoneData =
     # TODO: increase the TTL once things have settled down
-    data = ''
+    ''
       $ORIGIN ${domain}.
       $TTL 500
 
@@ -87,7 +30,7 @@ in
 
       ; NS (Name Server)
       @ NS ns
-      @ NS ${info.gandi.dns.secondary.ns.name}.
+      ${lib.concatMapStringsSep "\n" ({ name, ... }: "@ NS ${name}.") info.lebureau.dns.secondary.ns}
       i NS ns
       whoami4 NS ns.whoami4
       ns.whoami4 A ${hosts.mermet._module.args.ipv4}
@@ -96,6 +39,7 @@ in
       @            A ${hosts.mermet._module.args.ipv4}
       mermet       A ${hosts.mermet._module.args.ipv4}
       autoconfig   A ${hosts.mermet._module.args.ipv4}
+      calibre      A ${hosts.mermet._module.args.ipv4}
       doc          A ${hosts.mermet._module.args.ipv4}
       git          A ${hosts.mermet._module.args.ipv4}
       imap         A ${hosts.mermet._module.args.ipv4}
@@ -108,17 +52,20 @@ in
       smtp         A ${hosts.mermet._module.args.ipv4}
       submission   A ${hosts.mermet._module.args.ipv4}
       www          A ${hosts.mermet._module.args.ipv4}
-      lemoutona5pattes A ${hosts.mermet._module.args.ipv4}
       croc         A ${hosts.mermet._module.args.ipv4}
       stun         A ${hosts.mermet._module.args.ipv4}
       turn         A ${hosts.mermet._module.args.ipv4}
       whoami       A ${hosts.mermet._module.args.ipv4}
-      code          A ${hosts.mermet._module.args.ipv4}
-      miniflux      A ${hosts.mermet._module.args.ipv4}
+      code         A ${hosts.mermet._module.args.ipv4}
+      miniflux     A ${hosts.mermet._module.args.ipv4}
+
+      ; MX (Mail eXchange)
+      @ 500 MX 5 mail
 
       ; CNAME (Canonical Name)
       openconcerto     CNAME losurdo
       xmpp             CNAME mermet
+      salons           CNAME mermet
       tmp              CNAME mermet
       proxy65          CNAME mermet
       cryptpad         CNAME losurdo
@@ -126,11 +73,15 @@ in
       cryptpad-files   CNAME losurdo
       cryptpad-sandbox CNAME losurdo
       mumble           CNAME mermet
-      freeciv          CNAME losurdo
       nix-serve        CNAME losurdo
       nix-extracache   CNAME losurdo
       nix-localcache   CNAME lan.losurdo
+      ; See https://keys.openpgp.org/about/usage#wkd-as-a-service
+      openpgpkey       CNAME wkd.keys.openpgp.org.
       sftp             CNAME losurdo
+      radicle-mermet   CNAME mermet
+      radicle          CNAME mermet
+      radicle-explorer CNAME radicle
 
       ; DMARC (Domain-based Message Authentication, Reporting and Conformance)
       _dmarc 3600 IN TXT "v=DMARC1; p=none; pct=100; rua=mailto:root+dmarc+aggregate@sourcephile.fr; ruf=mailto:root+dmarc+forensic@sourcephile.fr"
@@ -150,31 +101,148 @@ in
 
       ; CAA (Certificate Authority Authorization)
       ; DOC: https://blog.qualys.com/ssllabs/2017/03/13/caa-mandated-by-cabrowser-forum
-      @ CAA 128 issue "letsencrypt.org"
+      @ CAA 128 issue "letsencrypt.org; validationmethods=dns-01"
     '';
+in
+# Incorrect:
+# accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/78014180
+{
+  services.knot.settingsFreeform = {
+    remote.ns_iodine.address = "127.0.0.1@1053";
+    acl."acl_localhost_acme_${domainID}" = {
+      address = "127.0.0.1";
+      action = "update";
+      update-owner = "name";
+      update-owner-match = "equal";
+      update-owner-name = [ "_acme-challenge" ];
+      update-type = [ "TXT" ];
+    };
+    acl."acl_tsig_acme_${domainID}" = {
+      key = "acme_${domainID}";
+      action = "update";
+      update-owner = "name";
+      update-owner-match = "equal";
+      update-owner-name = [ "_acme-challenge" ];
+      update-type = [ "TXT" ];
+    };
+    acl."acl_tsig_losurdo_${domainID}" = {
+      key = "losurdo_${domainID}";
+      action = "update";
+      update-owner = "name";
+      update-owner-match = "equal";
+      update-owner-name = [
+        "losurdo"
+        "lan.losurdo"
+      ];
+      update-type = [
+        "A"
+        "AAAA"
+      ];
+    };
+    acl."acl_lebureau_${domainID}" = {
+      action = "transfer";
+      address = [
+        info.lebureau.dns.secondary.transfer.ns1.ipv4
+        info.lebureau.dns.secondary.transfer.ns1.ipv6
+        info.lebureau.dns.secondary.transfer.ns2.ipv4
+        info.lebureau.dns.secondary.transfer.ns2.ipv6
+      ];
+      key = "lebureau_${domainID}";
+    };
+    mod-dnsproxy.proxy_iodine = {
+      remote = "ns_iodine";
+      fallback = "off";
+    };
+    remote."secondary1_lebureau_${domainID}" = {
+      address = [
+        "${info.lebureau.dns.secondary.transfer.ns1.ipv4}@53"
+        "${info.lebureau.dns.secondary.transfer.ns1.ipv6}@53"
+      ];
+      key = "lebureau_${domainID}";
+    };
+    remote."secondary2_lebureau_${domainID}" = {
+      address = [
+        "${info.lebureau.dns.secondary.transfer.ns2.ipv4}@53"
+        "${info.lebureau.dns.secondary.transfer.ns2.ipv6}@53"
+      ];
+      key = "lebureau_${domainID}";
+    };
+    zone."${domain}" = {
+      file = "${domain}.zone";
+      serial-policy = "increment";
+      semantic-checks = true;
+      notify = [
+        "secondary1_lebureau_${domainID}"
+        "secondary2_lebureau_${domainID}"
+      ];
+      acl = [
+        "acl_localhost_acme_${domainID}"
+        "acl_tsig_acme_${domainID}"
+        "acl_tsig_losurdo_${domainID}"
+        "acl_lebureau_${domainID}"
+      ];
+      dnssec-signing = true;
+      dnssec-policy = "ed25519";
+    };
+    #zone."i.${domain}" = {
+    #  module = "mod-dnsproxy/proxy_iodine";
+    #};
+    zone."whoami4.${domain}" = {
+      module = "mod-whoami";
+      file = pkgs.writeText "whoami4.zone" ''
+        $TTL 1
+        @ SOA ns root.${domain}. (
+          0     ; SERIAL
+          86400 ; REFRESH
+          86400 ; RETRY
+          86400 ; EXPIRE
+          1 ; MINIMUM
+        )
+        $TTL 86400
+        @ NS ns
+        ns A ${hosts.mermet._module.args.ipv4}
+      '';
+    };
   };
   services.knot = {
     keyFiles = [
       "/run/credentials/knot.service/${domain}.acme.conf"
       # Generated with: keymgr -t losurdo_${domainID}
       "/run/credentials/knot.service/losurdo.conf"
+      # Generated with: keymgr -t lebureau_${domainID}
+      "/run/credentials/knot.service/${domain}.lebureau.conf"
     ];
   };
   systemd.services.knot = {
     serviceConfig = {
+      ExecStartPre = [
+        ''
+          +${pkgs.coreutils}/bin/install -D -o ${users.knot.name} -g ${groups."knot".name} -m 700 \
+           ${pkgs.writeText "${domain}.zone" zoneData} \
+           /var/lib/knot/zones/${domain}.zone
+        ''
+      ];
       LoadCredentialEncrypted = [
-        "${domain}.acme.conf:${./. + "/${domain}/acme.conf.cred"}"
-        "losurdo.conf:${./. + "/${domain}/losurdo.conf.cred"}"
+        "${domain}.acme.conf:${builtins.path { path = ./. + "/${domain}/acme.conf.cred"; }}"
+        "${domain}.lebureau.conf:${builtins.path { path = ./. + "/${domain}/lebureau.conf.cred"; }}"
+        "losurdo.conf:${builtins.path { path = ./. + "/${domain}/losurdo.conf.cred"; }}"
       ];
     };
   };
   networking.nftables.ruleset = ''
     table inet filter {
-      set output-net-knot-ipv4 { type ipv4_addr; elements = { ${info.gandi.dns.secondary.axfr.ipv4} }; }
-      set output-net-knot-ipv6 { type ipv6_addr; elements = { ${info.gandi.dns.secondary.axfr.ipv6} }; }
+      set output-net-knot-ipv4 { type ipv4_addr; elements = {
+        ${info.lebureau.dns.secondary.transfer.ns1.ipv4},
+        ${info.lebureau.dns.secondary.transfer.ns2.ipv4}
+      }; }
+      set output-net-knot-ipv6 { type ipv6_addr; elements = {
+        ${info.lebureau.dns.secondary.transfer.ns1.ipv6},
+        ${info.lebureau.dns.secondary.transfer.ns2.ipv6}
+      }; }
     }
   '';
-  /* Useless since the zone is public
+  /*
+    Useless since the zone is public
     services.unbound.settings = {
     stub-zone = {
     name = domain;