mirror of
https://github.com/JulienMalka/snowfield.git
synced 2025-03-23 20:30:52 +01:00
feat: init backup module
This commit is contained in:
parent
71693eaa99
commit
23fc74efa6
7 changed files with 169 additions and 0 deletions
|
@ -57,6 +57,8 @@
|
|||
};
|
||||
};
|
||||
|
||||
services.backup.includes = [ "/var/lib/stalwart-mail/db" ];
|
||||
|
||||
age.secrets.stalwart-admin-hash = {
|
||||
file = ../../secrets/stalwart-admin.age;
|
||||
path = "/var/lib/stalwart-mail/admin-hash";
|
||||
|
|
16
machines/gustave/borg.nix
Normal file
16
machines/gustave/borg.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
users.users.borg = {
|
||||
home = "/home/borg";
|
||||
group = "borg";
|
||||
isNormalUser = true;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAziNbLEO9D69xUGPGEq3eXYauFuOlvhqQTwpLNKjFqs julien@tower"
|
||||
];
|
||||
|
||||
};
|
||||
users.groups.borg = { };
|
||||
|
||||
environment.systemPackages = with pkgs; [ borgbackup ];
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
./hardware.nix
|
||||
./home-julien.nix
|
||||
./nsd.nix
|
||||
./borg.nix
|
||||
];
|
||||
|
||||
machine.meta = {
|
||||
|
|
135
modules/backup/default.nix
Normal file
135
modules/backup/default.nix
Normal file
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.backup;
|
||||
# We backup on gustave
|
||||
host = "gustave.luj";
|
||||
port = "45";
|
||||
hostPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDJrHUzjPX0v2FX5gJALCjEJaUJ4sbfkv8CBWc6zm0Oe";
|
||||
sshKey = config.age.secrets."borg-ssh-key".path;
|
||||
secretPath = config.age.secrets."borg-encryption-secret".path;
|
||||
|
||||
in
|
||||
{
|
||||
options.services.backup =
|
||||
with lib;
|
||||
with types;
|
||||
{
|
||||
quota = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
example = "90G";
|
||||
description = ''
|
||||
Quota for the borg repository. Useful to prevent the target disk from running full and ensuring borg keeps some space to work with.
|
||||
'';
|
||||
};
|
||||
|
||||
includes = mkOption {
|
||||
type = listOf path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Paths to include in the backup.
|
||||
'';
|
||||
};
|
||||
|
||||
excludes = mkOption {
|
||||
type = listOf path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Paths to exclude in the backup.
|
||||
'';
|
||||
};
|
||||
|
||||
preHook = mkOption {
|
||||
type = lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell commands to run before the backup.
|
||||
'';
|
||||
};
|
||||
|
||||
postHook = mkOption {
|
||||
type = lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell commands to run after the backup.
|
||||
'';
|
||||
};
|
||||
|
||||
wantedUnits = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of units to require before starting the backup.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.includes != [ ]) {
|
||||
|
||||
age.secrets."borg-ssh-key" = {
|
||||
file = ../../secrets/borg-ssh-priv.age;
|
||||
owner = "root";
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
age.secrets."borg-encryption-secret".file = ../../secrets/borg-encryption-secret.age;
|
||||
|
||||
programs.ssh.knownHosts."${if port != 22 then "[${host}]:${port}" else host}" = {
|
||||
publicKey = "${hostPublicKey}";
|
||||
};
|
||||
|
||||
systemd.services.borgbackup-job-state = {
|
||||
wants = cfg.wantedUnits;
|
||||
after = cfg.wantedUnits;
|
||||
};
|
||||
|
||||
systemd.timers.borgbackup-job-state.timerConfig = {
|
||||
# Spread all backups over the day
|
||||
RandomizedDelaySec = "30m";
|
||||
FixedRandomDelay = true;
|
||||
};
|
||||
|
||||
services.borgbackup.jobs.state = {
|
||||
inherit (cfg) preHook postHook;
|
||||
|
||||
# Create the repo
|
||||
doInit = true;
|
||||
|
||||
# Create daily backups, but prune to a reasonable amount
|
||||
startAt = [ "hourly" ];
|
||||
prune.keep = {
|
||||
daily = 7;
|
||||
weekly = 4;
|
||||
monthly = 3;
|
||||
};
|
||||
|
||||
# What to backup
|
||||
paths = cfg.includes;
|
||||
exclude = cfg.excludes;
|
||||
|
||||
# Where to backup it to
|
||||
repo = "borg@gustave.luj:${config.networking.hostName}";
|
||||
environment.BORG_RSH = "ssh -p ${port} -i ${sshKey}";
|
||||
|
||||
# Ensure we don't fill up the destination disk
|
||||
extraInitArgs = lib.optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}";
|
||||
|
||||
# Authenticated & encrypted, key resides in the repository
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat ${secretPath}";
|
||||
};
|
||||
|
||||
# Reduce the backup size
|
||||
compression = "auto,zstd";
|
||||
|
||||
# Show summary detailing data usage once completed
|
||||
extraCreateArgs = "--stats";
|
||||
};
|
||||
};
|
||||
}
|
7
secrets/borg-encryption-secret.age
Normal file
7
secrets/borg-encryption-secret.age
Normal file
|
@ -0,0 +1,7 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 81O5Zw WCIdHHk7nehDc0n0u4Df17oVi2OIg+WT2FxM9uUMBTM
|
||||
ZufMHxTCazJycMSqHYKiGoRQUR+mPwXi/xsZQxIkjUM
|
||||
-> ssh-ed25519 AqX2tg kYJ4UZixeb7WjkXzdtS6Bgm0JQBLNUdONJbjsTtkaQM
|
||||
2H4qDAAlSJ3TNOF/UFOBlNnyAy1BclMvTv58fMJctuo
|
||||
--- s3weoMhZdAdfJ4rTU5E3x56PhlM6N3JfbdJOtQFjACM
|
||||
FCË"<22>a¤^Cð2bÓ=Âb‘gÝ$MéA”¤~Áð·T<05>4`ýöÚ§'žÚý¶.¶r’öPŸ¿ˆ®eÓÔìþ¡ÍÎCã
|
BIN
secrets/borg-ssh-priv.age
Normal file
BIN
secrets/borg-ssh-priv.age
Normal file
Binary file not shown.
|
@ -81,4 +81,12 @@ in
|
|||
tower
|
||||
];
|
||||
"arkheon-token.age".publicKeys = servers;
|
||||
"borg-ssh-priv.age".publicKeys = [
|
||||
akhaten
|
||||
tower
|
||||
];
|
||||
"borg-encryption-secret.age".publicKeys = [
|
||||
akhaten
|
||||
tower
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue