zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 3ed437b6a01c043c7e397d5243474cb476fc5755
parent 74a074c98cd15a326fb188515f15eee453919658
Author: Katja (zaphyra) <git@ctu.cx>
Date: Wed, 4 Jun 2025 12:31:24 +0200

add impermanence stuff to (web)services
12 files changed, 238 insertions(+), 105 deletions(-)
diff --git a/config/nixos/modules/presets/katja/mailServer.nix b/config/nixos/modules/presets/katja/mailServer.nix
@@ -155,6 +155,43 @@ in
         };
       };
 
+      modules.filesystem.impermanence.system.dirs = [
+        "/var/lib/dhparams"
+        "/var/lib/dovecot"
+        "/var/lib/postfix"
+        {
+          directory = "/var/lib/dkimKeys";
+          mode = "0700";
+          user = "rspamd";
+          group = "rspamd";
+        }
+        {
+          directory = "/var/lib/mailboxes";
+          mode = "0700";
+          user = "virtualMail";
+          group = "virtualMail";
+        }
+        {
+          directory = "/var/lib/redis-rspamd";
+          mode = "0700";
+          user = "redis-rspamd";
+          group = "redis-rspamd";
+        }
+        {
+          directory = "/var/lib/rspamd";
+          mode = "0700";
+          user = "rspamd";
+          group = "rspamd";
+        }
+        {
+          directory = "/var/lib/sieve";
+          mode = "0770";
+          user = "virtualMail";
+          group = "virtualMail";
+        }
+      ];
+
+
       security.acme.certs."${cfg.hostName}".reloadServices = [
         "postfix.service"
         "dovecot2.service"
diff --git a/config/nixos/modules/services/gitolite.nix b/config/nixos/modules/services/gitolite.nix
@@ -107,6 +107,15 @@ in
 
     in
     {
+      modules.filesystem.impermanence.system.dirs = [
+        {
+          directory = cfg.dataDir;
+          mode = "0755";
+          user = cfg.user;
+          group = cfg.group;
+        }
+      ];
+
       modules.services.gitolite.extraGitoliteRc = ''
         $RC{LOCAL_CODE} = "$ENV{HOME}/.gitolite/local";
       '';
diff --git a/config/nixos/modules/services/gotosocial.nix b/config/nixos/modules/services/gotosocial.nix
@@ -92,7 +92,14 @@ in
         }
       ];
 
-      modules.filesystem.impermanence.system.dirs = [ cfg.stateDir ];
+      modules.filesystem.impermanence.system.dirs = [
+        {
+          directory = cfg.stateDir;
+          mode = "0755";
+          user = cfg.user;
+          group = cfg.group;
+        }
+      ];
 
       modules.services.gotosocial.settings = {
         # Defaults
diff --git a/config/nixos/modules/services/mautrixBridge.nix b/config/nixos/modules/services/mautrixBridge.nix
@@ -7,9 +7,10 @@
 }:
 let
   inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
   forEachInstance =
     f:
-    lib.flip lib.mapAttrs' (lib.getAttrFromPath povSelf config) (
+    lib.flip lib.mapAttrs' cfg (
       name: cfg: lib.nameValuePair "mautrixBridge-${name}" (f name cfg)
     );
 

@@ -45,108 +46,115 @@ in
     );
   };
 
-  config.systemd.services = forEachInstance (
-    name: cfg:
-    let
-      dataDir = "/var/lib/mautrix-${name}";
-      registrationFile = "${dataDir}/registration.yaml";
-      settingsFile = "${dataDir}/config.yaml";
-      settingsFileUnsubstituted =
-        (pkgs.formats.json { }).generate "mautrix-${name}-config-unsubstituted.json"
-          cfg.settings;
-    in
-    {
-      enable = cfg.enable;
-      description = "mautrixBridge-${name}, a matrix puppeting bridge.";
-      restartTriggers = [ settingsFileUnsubstituted ];
-
-      wantedBy = [ "multi-user.target" ];
-      wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
-      after = [ "network-online.target" ] ++ cfg.serviceDependencies;
-
-      path = [ pkgs.ffmpeg-headless ];
-
-      preStart = ''
-        # substitute the settings file by environment variables
-        # in this case read from EnvironmentFile
-        test -f '${settingsFile}' && rm -f '${settingsFile}'
-        old_umask=$(umask)
-        umask 0177
-        ${pkgs.envsubst}/bin/envsubst \
-          -o '${settingsFile}' \
-          -i '${settingsFileUnsubstituted}'
-        umask $old_umask
-
-        # generate the appservice's registration file if absent
-        if [ ! -f '${registrationFile}' ]; then
-          ${lib.getExe cfg.package} \
-            --generate-registration \
-            --config='${settingsFile}' \
-            --registration='${registrationFile}'
-        fi
-        chmod 640 ${registrationFile}
-
-        umask 0177
-        ${pkgs.yq}/bin/yq -s '
-            .[0].appservice.as_token = (.[0].appservice.as_token // .[1].as_token)
-          | .[0].appservice.hs_token = (.[0].appservice.hs_token // .[1].hs_token)
-        ${lib.optionalString (
-          name == "telegram"
-        ) "
-        | .[0].network.api_id = (.[0].network.api_id | tonumber)
-      "}
-          | .[0]' \
-          '${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
-        mv '${settingsFile}.tmp' '${settingsFile}'
-        umask $old_umask
-      '';
-
-      serviceConfig = {
-        Type = "exec";
-
-        DynamicUser = true;
-        User = "mautrixBridge-${name}";
-        Group = "mautrixBridge-${name}";
-
-        EnvironmentFile = cfg.environmentFile;
-        StateDirectory = baseNameOf dataDir;
-        WorkingDirectory = dataDir;
-        UMask = 27;
-
-        ExecStart = ''
-          ${lib.getExe cfg.package} \
-          --no-update \
-          --config='${settingsFile}'
+  config = {
+    modules.filesystem.impermanence.system.dirs = (
+      (lib.attrNames cfg)
+      |> lib.map (element: "/var/lib/private/mautrix-${element}")
+    );
+
+    systemd.services = forEachInstance (
+      name: cfg:
+      let
+        dataDir = "/var/lib/mautrix-${name}";
+        registrationFile = "${dataDir}/registration.yaml";
+        settingsFile = "${dataDir}/config.yaml";
+        settingsFileUnsubstituted =
+          (pkgs.formats.json { }).generate "mautrix-${name}-config-unsubstituted.json"
+            cfg.settings;
+      in
+      {
+        enable = cfg.enable;
+        description = "mautrixBridge-${name}, a matrix puppeting bridge.";
+        restartTriggers = [ settingsFileUnsubstituted ];
+
+        wantedBy = [ "multi-user.target" ];
+        wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
+        after = [ "network-online.target" ] ++ cfg.serviceDependencies;
+
+        path = [ pkgs.ffmpeg-headless ];
+
+        preStart = ''
+          # substitute the settings file by environment variables
+          # in this case read from EnvironmentFile
+          test -f '${settingsFile}' && rm -f '${settingsFile}'
+          old_umask=$(umask)
+          umask 0177
+          ${pkgs.envsubst}/bin/envsubst \
+            -o '${settingsFile}' \
+            -i '${settingsFileUnsubstituted}'
+          umask $old_umask
+
+          # generate the appservice's registration file if absent
+          if [ ! -f '${registrationFile}' ]; then
+            ${lib.getExe cfg.package} \
+              --generate-registration \
+              --config='${settingsFile}' \
+              --registration='${registrationFile}'
+          fi
+          chmod 640 ${registrationFile}
+
+          umask 0177
+          ${pkgs.yq}/bin/yq -s '
+              .[0].appservice.as_token = (.[0].appservice.as_token // .[1].as_token)
+            | .[0].appservice.hs_token = (.[0].appservice.hs_token // .[1].hs_token)
+          ${lib.optionalString (
+            name == "telegram"
+          ) "
+          | .[0].network.api_id = (.[0].network.api_id | tonumber)
+        "}
+            | .[0]' \
+            '${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
+          mv '${settingsFile}.tmp' '${settingsFile}'
+          umask $old_umask
         '';
 
-        Restart = "on-failure";
-        RestartSec = "30s";
-
-        LockPersonality = true;
-        NoNewPrivileges = true;
-        MemoryDenyWriteExecute = lib.mkIf (name != "signal") true;
-
-        PrivateDevices = true;
-        PrivateTmp = true;
-        PrivateUsers = true;
-
-        ProtectSystem = "strict";
-        ProtectClock = true;
-        ProtectHome = true;
-        ProtectHostname = true;
-        ProtectKernelLogs = true;
-        ProtectKernelModules = true;
-        ProtectKernelTunables = true;
-        ProtectControlGroups = true;
-
-        RestrictRealtime = true;
-        RestrictSUIDSGID = true;
-
-        SystemCallArchitectures = "native";
-        SystemCallErrorNumber = "EPERM";
-        SystemCallFilter = [ "@system-service" ];
-      };
-    }
-  );
+        serviceConfig = {
+          Type = "exec";
+
+          DynamicUser = true;
+          User = "mautrixBridge-${name}";
+          Group = "mautrixBridge-${name}";
+
+          EnvironmentFile = cfg.environmentFile;
+          StateDirectory = baseNameOf dataDir;
+          WorkingDirectory = dataDir;
+          UMask = 27;
+
+          ExecStart = ''
+            ${lib.getExe cfg.package} \
+            --no-update \
+            --config='${settingsFile}'
+          '';
+
+          Restart = "on-failure";
+          RestartSec = "30s";
+
+          LockPersonality = true;
+          NoNewPrivileges = true;
+          MemoryDenyWriteExecute = lib.mkIf (name != "signal") true;
+
+          PrivateDevices = true;
+          PrivateTmp = true;
+          PrivateUsers = true;
+
+          ProtectSystem = "strict";
+          ProtectClock = true;
+          ProtectHome = true;
+          ProtectHostname = true;
+          ProtectKernelLogs = true;
+          ProtectKernelModules = true;
+          ProtectKernelTunables = true;
+          ProtectControlGroups = true;
+
+          RestrictRealtime = true;
+          RestrictSUIDSGID = true;
+
+          SystemCallArchitectures = "native";
+          SystemCallErrorNumber = "EPERM";
+          SystemCallFilter = [ "@system-service" ];
+        };
+      }
+    );
+  };
 
 }
diff --git a/config/nixos/modules/websites/bikemap.zaphyra.eu.nix b/config/nixos/modules/websites/bikemap.zaphyra.eu.nix
@@ -47,6 +47,15 @@ in
 
       dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
 
+      modules.filesystem.impermanence.system.dirs = [
+        {
+          directory = "/var/lib/bikemap";
+          mode = "0755";
+          user = "bikemap";
+          group = config.modules.services.gitolite.group;
+        }
+      ];
+
       users.users."bikemap" = {
         isSystemUser = true;
         group = config.modules.services.gitolite.group;
diff --git a/config/nixos/modules/websites/dav.zaphyra.eu.nix b/config/nixos/modules/websites/dav.zaphyra.eu.nix
@@ -32,10 +32,19 @@ in
   config = lib.mkIf cfg.enable {
     dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/radicale";
+        mode = "0700";
+        user = config.systemd.services.radicale.serviceConfig.User;
+        group = config.systemd.services.radicale.serviceConfig.Group;
+      }
+    ];
+
     sops.secrets = {
       "resticPasswords/radicale" = { };
       radicaleUsers = {
-        owner = "radicale";
+        owner = config.systemd.services.radicale.serviceConfig.User;
         restartUnits = [ "radicale.service" ];
       };
     };

@@ -43,7 +52,7 @@ in
     modules.services.resticBackup.paths = {
       radicale = {
         enable = true;
-        user = "radicale";
+        user = config.systemd.services.radicale.serviceConfig.User;
         passwordFile = config.sops.secrets."resticPasswords/radicale".path;
         paths = [ config.services.radicale.settings.storage.filesystem_folder ];
       };
diff --git a/config/nixos/modules/websites/git.zaphyra.eu.nix b/config/nixos/modules/websites/git.zaphyra.eu.nix
@@ -169,6 +169,16 @@ in
         "ctu.cx".subdomains."cgit".CNAME = [ "${config.networking.fqdn}." ];
       };
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/stagit";
+        mode = "0755";
+        user = "git";
+        group = "git";
+      }
+    ];
+
+
       sops.secrets."resticPasswords/gitolite" = {
         owner = "git";
       };
diff --git a/config/nixos/modules/websites/grafana.infra.zaphyra.eu.nix b/config/nixos/modules/websites/grafana.infra.zaphyra.eu.nix
@@ -36,6 +36,15 @@ in
   config = lib.mkIf cfg.enable {
     dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/grafana";
+        mode = "0700";
+        user = "grafana";
+        group = "grafana";
+      }
+    ];
+
     services.grafana = {
       enable = true;
       settings = {
diff --git a/config/nixos/modules/websites/grapevine.zaphyra.eu.nix b/config/nixos/modules/websites/grapevine.zaphyra.eu.nix
@@ -43,6 +43,8 @@ in
 
     sops.secrets."resticPasswords/grapevine" = { };
 
+    modules.filesystem.impermanence.system.dirs = [ "/var/lib/private/grapevine" ];
+
     modules.services.resticBackup.paths = {
       grapevine = {
         enable = true;
diff --git a/config/nixos/modules/websites/prometheus.infra.zaphyra.eu.nix b/config/nixos/modules/websites/prometheus.infra.zaphyra.eu.nix
@@ -33,6 +33,15 @@ in
   config = lib.mkIf cfg.enable {
     dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/prometheus2";
+        mode = "0700";
+        user = "prometheus";
+        group = "prometheus";
+      }
+    ];
+
     services.prometheus = {
       enable = true;
       webExternalUrl = "https://${cfg.subdomain}.${cfg.domain}/";
diff --git a/config/nixos/modules/websites/things.zaphyra.eu.nix b/config/nixos/modules/websites/things.zaphyra.eu.nix
@@ -34,6 +34,15 @@ in
 
     sops.secrets."resticPasswords/things" = { };
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/things";
+        mode = "0700";
+        user = "things";
+        group = "things";
+      }
+    ];
+
     modules.services.resticBackup.paths = {
       things = {
         enable = true;
diff --git a/config/nixos/modules/websites/vault.zaphyra.eu.nix b/config/nixos/modules/websites/vault.zaphyra.eu.nix
@@ -32,6 +32,21 @@ in
   config = lib.mkIf cfg.enable {
     dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
 
+    modules.filesystem.impermanence.system.dirs = [
+      {
+        directory = "/var/lib/vaultwarden";
+        mode = "0700";
+        user = config.systemd.services.vaultwarden.serviceConfig.User;
+        group = config.systemd.services.vaultwarden.serviceConfig.Group;
+      }
+      {
+        directory = config.services.vaultwarden.backupDir;
+        mode = "0700";
+        user = config.systemd.services.vaultwarden.serviceConfig.User;
+        group = config.systemd.services.vaultwarden.serviceConfig.Group;
+      }
+    ];
+
     sops.secrets = {
       "resticPasswords/vaultwarden" = { };
       "environments/vaultwarden" = {