mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 23:00:39 +02:00
feat: add restic hetzner module, script still wip
This commit is contained in:
parent
1165dc44aa
commit
a464c99fb8
7 changed files with 106 additions and 0 deletions
|
@ -160,6 +160,8 @@
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
// flake-utils.lib.eachDefaultSystem (system: rec {
|
// flake-utils.lib.eachDefaultSystem (system: rec {
|
||||||
|
apps.setupHetznerStorageBoxes = import ./nix/setup-hetzner-storage-boxes.nix self;
|
||||||
|
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
|
|
|
@ -80,6 +80,7 @@ in {
|
||||||
"rpool/local/state<" = true;
|
"rpool/local/state<" = true;
|
||||||
"rpool/safe<" = true;
|
"rpool/safe<" = true;
|
||||||
"storage/safe<" = true;
|
"storage/safe<" = true;
|
||||||
|
"storage/bunker<" = true;
|
||||||
};
|
};
|
||||||
snapshotting = {
|
snapshotting = {
|
||||||
type = "periodic";
|
type = "periodic";
|
||||||
|
|
|
@ -209,4 +209,37 @@ in {
|
||||||
];
|
];
|
||||||
|
|
||||||
users.groups = lib.mapAttrs (_: cfg: {gid = cfg.id;}) (smbUsers // smbGroups);
|
users.groups = lib.mapAttrs (_: cfg: {gid = cfg.id;}) (smbUsers // smbGroups);
|
||||||
|
|
||||||
|
# Backups
|
||||||
|
# ========================================================================
|
||||||
|
|
||||||
|
age.secrets.restic-encryption-password.generator.script = "alnum";
|
||||||
|
age.secrets.restic-ssh-privkey.generator.script = "ssh-ed25519";
|
||||||
|
|
||||||
|
services.restic.backups.main = {
|
||||||
|
hetznerStorageBox = let
|
||||||
|
box = config.repo.secrets.global.hetzner.storageboxes.dusk;
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
inherit (box) mainUser;
|
||||||
|
inherit (box.users.samba) subUid path;
|
||||||
|
sshPrivateKeyFile = config.age.secrets.restic-ssh-privkey.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
user = "root";
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "06:15";
|
||||||
|
RandomizedDelaySec = "3h";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
initialize = true;
|
||||||
|
passwordFile = config.age.secrets.restic-encryption-password.path;
|
||||||
|
paths = ["/bunker"];
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-daily 14"
|
||||||
|
"--keep-weekly 7"
|
||||||
|
"--keep-monthly 12"
|
||||||
|
"--keep-yearly 75"
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
./oauth2-proxy.nix
|
./oauth2-proxy.nix
|
||||||
./promtail.nix
|
./promtail.nix
|
||||||
./provided-domains.nix
|
./provided-domains.nix
|
||||||
|
./restic.nix
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
./telegraf.nix
|
./telegraf.nix
|
||||||
./wireguard-proxy.nix
|
./wireguard-proxy.nix
|
||||||
|
|
57
modules/restic.nix
Normal file
57
modules/restic.nix
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{lib, ...}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
;
|
||||||
|
in {
|
||||||
|
options.services.restic.backups = {
|
||||||
|
type = types.attrsOf (types.submodule ({config}: {
|
||||||
|
options.hetznerStorageBox = {
|
||||||
|
enable = mkEnableOption "Automatically configure this backup to use the given hetzner storage box. Will use SFTP via SSH.";
|
||||||
|
|
||||||
|
mainUser = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The main user. While not technically required for restic, we still use it to
|
||||||
|
derive the subuser name and it is required for the automatic setup script
|
||||||
|
that creates the users.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
subUid = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
description = "The id of the subuser that was allocated on the hetzner server for this backup.";
|
||||||
|
};
|
||||||
|
|
||||||
|
path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The remote path to backup into. While not technically required for restic
|
||||||
|
(since the subuser is chrooted on the remote), we'll still use it to set
|
||||||
|
a sane repository and it is required for the automatic setup script that
|
||||||
|
creates the users.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sshPrivateKeyFile = {
|
||||||
|
type = types.path;
|
||||||
|
description = "The path to the ssh private key to use for uploading backups. Don't use a path from the nix store!";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
subUser = "${config.hetznerStorageBox.mainUser}-sub${toString config.hetznerStorageBox.subUid}";
|
||||||
|
url = "${subUser}@${subUser}.your-storagebox.de";
|
||||||
|
in
|
||||||
|
mkIf config.hetznerStorageBox.enable {
|
||||||
|
repository = "sftp://${url}:23${config.hetznerStorageBox.path}";
|
||||||
|
extraOptions = [
|
||||||
|
"sftp.command='ssh -s sftp -p 23 -i ${config.hetznerStorageBox.sshPrivateKeyFile} ${url}'"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}
|
12
nix/setup-hetzner-storage-boxes.nix
Normal file
12
nix/setup-hetzner-storage-boxes.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
self: system: let
|
||||||
|
pkgs = self.pkgs.${system};
|
||||||
|
in {
|
||||||
|
type = "app";
|
||||||
|
drv = pkgs.writeShellApplication {
|
||||||
|
name = "setup-hetzner-storage-boxes";
|
||||||
|
text = ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue