diff --git a/.gitattributes b/.gitattributes index 6d34fee..6f6b429 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ #pattern filter=crypt diff=crypt **/*.crypt filter=crypt diff=crypt home/ssh/id_rsa* filter=crypt diff=crypt +hosts/linode/ssh/id_* filter=crypt diff=crypt diff --git a/hosts/linode/default.nix b/hosts/linode/default.nix index ae0a13c..a947538 100644 --- a/hosts/linode/default.nix +++ b/hosts/linode/default.nix @@ -11,6 +11,7 @@ greg.home = false; greg.linode.enable = true; greg.tailscale.enable = true; + greg.backup.key = ./ssh/id_ed25519; networking.hostName = "linode"; networking.domain = "thehellings.com"; } diff --git a/hosts/linode/nextcloud.nix b/hosts/linode/nextcloud.nix index 068ec5a..9a87315 100644 --- a/hosts/linode/nextcloud.nix +++ b/hosts/linode/nextcloud.nix @@ -25,9 +25,9 @@ enableACME = true; }; - services.syncthing.folders."nextcloud-backup" = { - path = "${config.services.nextcloud.datadir}"; - enable = true; - devices = [ "nas" ]; + greg.backup.jobs.nextcloud = { + src = "/var/lib/nextcloud"; + dest = "nextcloud-backup"; + user = "nextcloud"; }; } diff --git a/hosts/linode/postgres.nix b/hosts/linode/postgres.nix index 319c962..df3a507 100644 --- a/hosts/linode/postgres.nix +++ b/hosts/linode/postgres.nix @@ -38,16 +38,20 @@ root root postgres services.logrotate = { enable = true; settings = { - postgres = { + postgresBackup = { enable = true; files = "${config.services.postgresqlBackup.location}/*.gz"; }; + postgresLog = { + enable = true; + files = "/var/lib/postgresql/*/log/*.log"; + }; }; }; - services.syncthing.folders."postgres-backups" = { - path = "${config.services.postgresqlBackup.location}"; - enable = true; - devices = [ "nas" ]; + greg.backup.jobs.postgresql = { + src = "/var/backup/postgresql"; + dest = "linode-postgres"; + user = "postgres"; }; } diff --git a/hosts/linode/ssh/id_ed25519 b/hosts/linode/ssh/id_ed25519 new file mode 100644 index 0000000..5cf4acf --- /dev/null +++ b/hosts/linode/ssh/id_ed25519 @@ -0,0 +1,9 @@ +U2FsdGVkX1+5xhF/T+xJUHDp5c4sT1d0SHp/bwqJ0WXOsiCv7pGNuDBVV1rhItct +tRnfR7OKwrfK7DXFCTNJkcYhnNwma8ZBurmFCwMpAC6sXGhEIoxHNkWezjlGnZja +k1cVx8R17Eg4/3jzKPyaCGv1kZ9Nhxg8aHtXP5ow2e6C0dzkQaq3j9QEVjRUm+tf +JY4Aetg+ySXvKVfdj0JnSkAu4k8IznxzEqzkdF7gcTdiYJo54VQXzupAjwe6BBrh ++ncgfBWaFOfq9Jiawh8HFFm48cOwsKh3+18itI9t8snhyANFj3pFiTsoCZBdYIxR +UwbfcRjDsyplCpwQNZaioe3bh/UMOZsFrUm4Ch8kR6nbJjfonl4nmnrSLHCY9lrn +QWscukwrLcwsAh4B0q0bhUPa3qCj9KQyml/iSKbOboIigbPu9IhFCP23POnFl0Rc +ehf+WQ+xtu49YPbvGjn6lhklHMDlJAM3HGp+/7c0b0VQ98ZzRBjqmIsrDmVKR9ba +1lVm6C+ootFhXrTrejFh4zmMSynL3P179d9O0936uY4= diff --git a/hosts/linode/ssh/id_ed25519.pub b/hosts/linode/ssh/id_ed25519.pub new file mode 100644 index 0000000..26d8d1d --- /dev/null +++ b/hosts/linode/ssh/id_ed25519.pub @@ -0,0 +1,3 @@ +U2FsdGVkX1/RfYko8CbloOVbd2J9+eCw/UuUw8YJ0Rm/G/yUZNeLU2yngUky/vsk +XxXZBVO+ScNGwgzvb4iDqx01szQtrT8cIpkhaetyUY11CLEgPr8fbcHX/XOfGctV +bUnljF9ubnNcmRzAzXjsfQ== diff --git a/modules/backup.nix b/modules/backup.nix new file mode 100644 index 0000000..ebc4a79 --- /dev/null +++ b/modules/backup.nix @@ -0,0 +1,107 @@ +{ lib, config, pkgs, ... }: + +let + cfg = config.greg.backup; + backup_key = "backup_keys/id_ed25519"; + + makeJob = name: job: { + paths = job.src; + encryption.mode = "none"; + environment.BORG_RSH = "ssh -i /etc/${backup_key} -o 'StrictHostKeyChecking=no' -o 'UserKnownHostsFile=/dev/null'"; + repo = "ssh://backup@nas.me.ts//volume1/NetBackup/${job.dest}"; + compression = "auto,zstd"; + startAt = "daily"; + + user = job.user; + group = job.group; + preHook = job.pre; + postHook = job.post; + }; + + cronJob = name: job: + let + binName = "backup-${name}"; + script = pkgs.writeShellScriptBin binName '' +exec 1> >(systemd-cat -t $(basename $0)) 2>&1 +set -ex +${job.pre} +${pkgs.rsync}/bin/rsync -avz --delete -e "${pkgs.openssh}/bin/ssh -i /etc/${backup_key} -o 'StrictHostKeyChecking=no' -o 'UserKnownHostsFile=/dev/null'" ${job.src}/* backup@nas.me.ts:/volume1/NetBackup/${job.dest}/ +${job.post} +''; + in { + inherit script; + cron = "0 0 1 * * ${job.user} ${script}/bin/${binName}"; + }; + +in with lib; { + options = { + greg.backup = { + key = mkOption { + type = types.path; + description = "SSH key to use"; + default = null; + }; + + jobs = mkOption { + default = {}; + + type = with types; attrsOf (submodule ( + { name, config, options, ... }: + { + options = { + src = mkOption { + type = types.str; + description = "Local path (string form) to backup from"; + }; + + dest = mkOption { + type = types.str; + }; + + user = mkOption { + type = types.str; + default = "root"; + description = "User to run backup as"; + }; + + pre = mkOption { + type = types.str; + default = ""; + description = "Commands to run before backup"; + }; + + post = mkOption { + type = types.str; + default = ""; + description = "Commands to run after backup"; + }; + }; + } + )); + }; + }; + }; + + config = let + jobs = attrValues ( mapAttrs cronJob cfg.jobs ); + in mkIf ( ( attrValues cfg.jobs ) != [] ) + { + #services.borgbackup = { + # jobs = mapAttrs makeJob cfg.jobs; + #}; + services.cron = { + enable = true; + systemCronJobs = map (e: e.cron) jobs; + }; + + environment.etc = mkIf ( cfg.key != null ) { + "${backup_key}" = { + user = "nobody"; + mode = "0777"; + source = cfg.key; + }; + }; + + environment.systemPackages = map (e: e.script) jobs; + }; +} diff --git a/modules/default.nix b/modules/default.nix index 2a2d0c4..a20e178 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -2,6 +2,7 @@ { imports = [ + ./backup.nix ./home.nix ./gnome.nix ./linode.nix diff --git a/profiles/base/syncthing.nix b/profiles/base/syncthing.nix index dc46abc..1bd8471 100644 --- a/profiles/base/syncthing.nix +++ b/profiles/base/syncthing.nix @@ -10,9 +10,9 @@ in { services.syncthing = { enable = true; - user = "root"; - group = "root"; - dataDir = "/root/sync"; + user = "greg"; + group = "users"; + dataDir = "/home/greg/sync"; devices = { nas = { addresses = [ @@ -35,5 +35,12 @@ in id = "ROZPUG5-G4IAXYA-JNRQXRD-5PFU2BQ-WVJTOGZ-DFMGJ5E-Q4IGXCJ-JHSNDQ6"; }; }; + folders = { + "mkrvy-tc6x9" = { + path = "/home/greg/drive"; + enable = true; + devices = syncs; + }; + }; }; }