diff --git a/flake.lock b/flake.lock
index 9710a30..e46b8ee 100644
--- a/flake.lock
+++ b/flake.lock
@@ -86,11 +86,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1679757516,
-        "narHash": "sha256-LAGtkIaz+f8uBI5WNvEbcyCkBCJi2ZdZRhn7OKoJjbo=",
+        "lastModified": 1683625533,
+        "narHash": "sha256-GvKE97JdQuEZ697TLSMRTNABbVJfGVnJ0vfzK4AIFyI=",
         "ref": "refs/heads/main",
-        "rev": "7e019abec4c6f5f9216028d0b4b51ddc037886f4",
-        "revCount": 16,
+        "rev": "5e86139ee4af27f84228708fd32903bb0c4230f0",
+        "revCount": 19,
         "type": "git",
         "url": "https://git.clerie.de/clerie/nixos-exporter.git"
       },
diff --git a/hosts/monitoring-3/nixos-validator.nix b/hosts/monitoring-3/nixos-validator.nix
index f8ee9ea..12ab7e0 100644
--- a/hosts/monitoring-3/nixos-validator.nix
+++ b/hosts/monitoring-3/nixos-validator.nix
@@ -1,27 +1,10 @@
 { pkgs, ... }:
 {
-
-  users.users."nixos-validator" = {
-    isSystemUser = true;
-    group = "nixos-validator";
+  services.nixos-validator = {
+    enable = true;
+    listen = "[::]:9153";
+    prometheusUrl = "http://[::1]:9090";
+    prometheusQueryTagTemplate = "instance=\"{}.net.clerie.de\"";
+    hydraUrl = "https://hydra.clerie.de";
   };
-
-  users.groups."nixos-validator" = {};
-
-  systemd.services."prometheus-nixos-validator" = {
-    wantedBy = [ "multi-user.target" ];
-    after = [ "network.target" ];
-    serviceConfig = {
-      Restart = "always";
-      PrivateTmp = true;
-      WorkingDirectory = "/tmp";
-      RuntimeDirectory = "prometheus-nixos-validator";
-      User = "nixos-validator";
-      Group = "nixos-validator";
-      ExecStart = ''
-        ${pkgs.nixos-exporter}/bin/nixos-exporter --listen [::]:9153 validator --prometheus-url "http://[::1]:9090" --prometheus-query-tag-template "instance=\"{}.net.clerie.de\"" --hydra-url "https://hydra.clerie.de"
-      '';
-    };
-  };
-
 }
diff --git a/lib/flake-helper.nix b/lib/flake-helper.nix
index 86ff576..c7586f4 100644
--- a/lib/flake-helper.nix
+++ b/lib/flake-helper.nix
@@ -28,14 +28,13 @@ rec {
           (_: _: {
             inherit (agenix.packages."x86_64-linux")
               agenix;
-            inherit (nixos-exporter.packages."x86_64-linux")
-              nixos-exporter;
            })
         ];
         clerie.monitoring = nixpkgs.lib.attrsets.optionalAttrs (group != null) { serviceLevel = group; };
       })
       agenix.nixosModules.default
       fernglas.nixosModules.default
+      nixos-exporter.nixosModules.default
       solid-xmpp-alarm.nixosModules.solid-xmpp-alarm
       (../hosts + "/${name}/configuration.nix")
       # Automatically load secrets from the hosts secrets directory
diff --git a/modules/backup/default.nix b/modules/backup/default.nix
new file mode 100644
index 0000000..cc60287
--- /dev/null
+++ b/modules/backup/default.nix
@@ -0,0 +1,95 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.clerie.backup;
+
+  generateBackupServiceUnit = jobName: job: let
+    targets = cfg.targets;
+    jobPasswordFile = if job.passwordFile == null then config.age."backup-job-${jobName}".path else job.passwordFile;
+    repoPath = if job.repoPath == null then "/${config.networking.hostName}/${jobName}" else job.repoPath;
+    unit = concatMapAttrs targetName: target: let
+        targetPasswordFile = if target.passwordFile == null then config.age."backup-target-${targetName}".path else target.passwordFile;
+        targetUsername = if target.username == null then config.networing.hostName else target.username;
+      in (nameValuePair "clerie-restic-backup-${jobName}-${targetName}" {
+      requires = [ "network.target" "local-fs.target" ];
+      path = [ pkgs.resic ];
+
+      serviceConfig = {
+        Type = "oneshot";
+      };
+
+      script = ''
+        set -euo pipefail
+
+        export RESTIC_PASSWORD_FILE=${jobPasswordFile}
+        export RESTIC_REPOSITORY="rest:https://${targetUsername}:$(cat ${targetPasswordFile})@${target.serverName}${repoPath}"
+
+        restic snapshots || restic init
+
+        restic backup ${escapeShellArgs job.paths}
+
+        restic check
+      ''});
+
+    in units;
+  };
+
+
+  targetOptions = { ... }: {
+    options = {
+      passwordFile = mkOption {
+        type = with types; nullOr str;
+        default = null;
+      };
+      username = mkOption {
+        type = with types; nullOr str;
+        default = null;
+      };
+      serverName = mkOption {
+        type = types.str;
+      };
+    };
+  };
+
+  jobModules = { ... }: {
+    options = {
+      passwordFile = mkOption {
+        type = with types; nullOr str;
+        default = null;
+      };
+      repoPath = mkOption {
+        type = with types; nullOr str;
+        default = null;
+      };
+      targets = mkOption {
+        type = with types; nullOr (listOf str);
+        defualt = null;
+      };
+      paths = mkOption {
+        type = with types; listOf str;
+      };
+    };
+  };
+in
+
+{
+  options = {
+    clerie.backup = {
+      enable = mkEnableOption "clerie's Backup";
+      targets = {
+        type = with types; attrsOF (submodule targetOptions);
+        default = {};
+      };
+      jobs = mkOption {
+        type = with types; attrsOf (submodule jobOptions);
+        default = {};
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services =  mapAttrs' generateBackupServiceUnit (cfg.jobs)
+  };
+}
diff --git a/modules/monitoring/default.nix b/modules/monitoring/default.nix
index 3083b00..dcb541d 100644
--- a/modules/monitoring/default.nix
+++ b/modules/monitoring/default.nix
@@ -95,27 +95,10 @@ in
       '';
     };
 
-    users.users."nixos-exporter" = {
-      isSystemUser = true;
-      group = "nixos-exporter";
-    };
 
-    users.groups."nixos-exporter" = {};
-
-    systemd.services."prometheus-nixos-exporter" = {
-      wantedBy = [ "multi-user.target" ];
-      after = [ "network.target" ];
-      serviceConfig = {
-        Restart = "always";
-        PrivateTmp = true;
-        WorkingDirectory = "/tmp";
-        RuntimeDirectory = "prometheus-nixos-exporter";
-        User = "nixos-exporter";
-        Group = "nixos-exporter";
-        ExecStart = ''
-          ${pkgs.nixos-exporter}/bin/nixos-exporter --listen [::]:9152 exporter
-        '';
-      };
+    services.nixos-exporter = {
+      enable = true;
+      listen = "[::]:9152";
     };
 
     networking.firewall.extraCommands = ''