From 3c5e34865b0face5b036bbe36ea950d8675f422d Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Mon, 6 Nov 2023 16:59:20 +0800 Subject: [PATCH] hosts/plover: modularize BorgBackup service --- hosts/plover/default.nix | 85 ++------------------ hosts/plover/modules/services/borgbackup.nix | 79 ++++++++++++++++++ 2 files changed, 85 insertions(+), 79 deletions(-) create mode 100644 hosts/plover/modules/services/borgbackup.nix diff --git a/hosts/plover/default.nix b/hosts/plover/default.nix index eea959c6..c0bdb4dd 100644 --- a/hosts/plover/default.nix +++ b/hosts/plover/default.nix @@ -1,12 +1,7 @@ { config, lib, pkgs, modulesPath, ... }: let - inherit (builtins) toString; inherit (import ./modules/hardware/networks.nix) interfaces; - - # The head of the Borgbase hostname. - hetzner-boxes-user = "u332477"; - hetzner-boxes-server = "${hetzner-boxes-user}.your-storagebox.de"; in { imports = [ @@ -22,6 +17,11 @@ in # Hardened profile from nixpkgs. "${modulesPath}/profiles/hardened.nix" + # Of course, what is a server without a backup? A professionally-handled + # production system. However, we're not professionals so we do have + # backups. + ./modules/services/borgbackup.nix + # The primary DNS server that is completely hidden. ./modules/services/bind.nix @@ -80,14 +80,10 @@ in }; }; + sops.secrets = lib.getSecrets ./secrets/secrets.yaml { "ssh-key" = { }; "lego/env" = { }; - - "borg/repos/host/patterns/keys" = { }; - "borg/repos/host/password" = { }; - "borg/repos/services/password" = { }; - "borg/ssh-key" = { }; }; # All of the keys required to deploy the secrets. @@ -118,74 +114,5 @@ in type = "ed25519"; }]; - # Of course, what is a server without a backup? A professionally-handled - # production system. However, we're not professionals so we do have backups. - services.borgbackup.jobs = - let - jobCommonSettings = { patternFiles ? [ ], patterns ? [ ], paths ? [ ], repo, passCommand }: { - inherit paths repo; - compression = "zstd,11"; - dateFormat = "+%F-%H-%M-%S-%z"; - doInit = true; - encryption = { - inherit passCommand; - mode = "repokey-blake2"; - }; - extraCreateArgs = - let - args = lib.flatten [ - (builtins.map - (patternFile: "--patterns-from ${lib.escapeShellArg patternFile}") - patternFiles) - (builtins.map - (pattern: "--pattern ${lib.escapeShellArg pattern}") - patterns) - ]; - in - lib.concatStringsSep " " args; - extraInitArgs = "--make-parent-dirs"; - persistentTimer = true; - preHook = '' - extraCreateArgs="$extraCreateArgs --stats" - ''; - prune.keep = { - weekly = 4; - monthly = 12; - yearly = 6; - }; - startAt = "monthly"; - environment.BORG_RSH = "ssh -i ${config.sops.secrets."borg/ssh-key".path}"; - }; - - borgRepo = path: "ssh://${hetzner-boxes-user}@${hetzner-boxes-server}:23/./borg/plover/${path}"; - in - { - # Backup for host-specific files. They don't change much so it is - # acceptable for it to be backed up monthly. - host-backup = jobCommonSettings { - patternFiles = [ - config.sops.secrets."borg/repos/host/patterns/keys".path - ]; - repo = borgRepo "host"; - passCommand = "cat ${config.sops.secrets."borg/repos/host/password".path}"; - }; - - # Backups for various services. - services-backup = jobCommonSettings - { - paths = [ - # ACME accounts and TLS certificates - "/var/lib/acme" - ]; - repo = borgRepo "services"; - passCommand = "cat ${config.sops.secrets."borg/repos/services/password".path}"; - } // { startAt = "daily"; }; - }; - - programs.ssh.extraConfig = '' - Host ${hetzner-boxes-server} - IdentityFile ${config.sops.secrets."borg/ssh-key".path} - ''; - system.stateVersion = "23.11"; } diff --git a/hosts/plover/modules/services/borgbackup.nix b/hosts/plover/modules/services/borgbackup.nix new file mode 100644 index 00000000..81821de1 --- /dev/null +++ b/hosts/plover/modules/services/borgbackup.nix @@ -0,0 +1,79 @@ +{ config, lib, pkgs, ... }: + +let + # The head of the Borgbase hostname. + hetzner-boxes-user = "u332477"; + hetzner-boxes-server = "${hetzner-boxes-user}.your-storagebox.de"; + borgRepo = path: "ssh://${hetzner-boxes-user}@${hetzner-boxes-server}:23/./borg/plover/${path}"; + + jobCommonSettings = { patternFiles ? [ ], patterns ? [ ], paths ? [ ], repo, passCommand }: { + inherit paths repo; + compression = "zstd,11"; + dateFormat = "+%F-%H-%M-%S-%z"; + doInit = true; + encryption = { + inherit passCommand; + mode = "repokey-blake2"; + }; + extraCreateArgs = + let + args = lib.flatten [ + (builtins.map + (patternFile: "--patterns-from ${lib.escapeShellArg patternFile}") + patternFiles) + (builtins.map + (pattern: "--pattern ${lib.escapeShellArg pattern}") + patterns) + ]; + in + lib.concatStringsSep " " args; + extraInitArgs = "--make-parent-dirs"; + persistentTimer = true; + preHook = '' + extraCreateArgs="$extraCreateArgs --stats" + ''; + prune.keep = { + weekly = 4; + monthly = 12; + yearly = 6; + }; + startAt = "monthly"; + environment.BORG_RSH = "ssh -i ${config.sops.secrets."borg/ssh-key".path}"; + }; +in +{ + sops.secrets = lib.getSecrets ../../secrets/secrets.yaml { + "borg/repos/host/patterns/keys" = { }; + "borg/repos/host/password" = { }; + "borg/repos/services/password" = { }; + "borg/ssh-key" = { }; + }; + + services.borgbackup.jobs = { + # Backup for host-specific files. They don't change much so it is + # acceptable for it to be backed up monthly. + host-backup = jobCommonSettings { + patternFiles = [ + config.sops.secrets."borg/repos/host/patterns/keys".path + ]; + repo = borgRepo "host"; + passCommand = "cat ${config.sops.secrets."borg/repos/host/password".path}"; + }; + + # Backups for various services. + services-backup = jobCommonSettings + { + paths = [ + # ACME accounts and TLS certificates + "/var/lib/acme" + ]; + repo = borgRepo "services"; + passCommand = "cat ${config.sops.secrets."borg/repos/services/password".path}"; + } // { startAt = "daily"; }; + }; + + programs.ssh.extraConfig = '' + Host ${hetzner-boxes-server} + IdentityFile ${config.sops.secrets."borg/ssh-key".path} + ''; +}