From 378cf47683d8bd2a5f68e5140e25d669863c9af2 Mon Sep 17 00:00:00 2001 From: Zuckerberg Date: Sat, 8 Apr 2023 21:25:55 -0600 Subject: [PATCH] restic backups --- common/backups.nix | 56 +++++++++++++++++++++++++++++++ common/default.nix | 1 + common/network/hosts.nix | 10 ++---- common/network/tailscale.nix | 2 +- common/server/gitea.nix | 17 ++++++++-- common/server/mailserver.nix | 5 +++ common/server/nextcloud.nix | 6 ++++ common/server/samba.nix | 7 ++++ common/server/thelounge.nix | 4 +++ flake.lock | 2 +- machines/ponyo/configuration.nix | 3 ++ secrets/backblaze-s3-backups.age | Bin 0 -> 1213 bytes secrets/restic-password.age | Bin 0 -> 1076 bytes secrets/secrets.nix | 28 +++++++++++----- 14 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 common/backups.nix create mode 100644 secrets/backblaze-s3-backups.age create mode 100644 secrets/restic-password.age diff --git a/common/backups.nix b/common/backups.nix new file mode 100644 index 0000000..90bae20 --- /dev/null +++ b/common/backups.nix @@ -0,0 +1,56 @@ +{ config, lib, ... }: + +let + cfg = config.backup; + hostname = config.networking.hostName; + + mkBackup = group: paths: { + repository = "s3:s3.us-west-004.backblazeb2.com/D22TgIt0-main-backup/${group}"; + inherit paths; + + initialize = true; + + timerConfig = { + OnCalendar = "daily"; + RandomizedDelaySec = "1h"; + }; + + pruneOpts = [ + "--keep-daily 7" # one backup for each of the last n days + "--keep-weekly 5" # one backup for each of the last n weeks + "--keep-monthly 12" # one backup for each of the last n months + "--keep-yearly 75" # one backup for each of the last n years + ]; + + environmentFile = "/run/agenix/backblaze-s3-backups"; + passwordFile = "/run/agenix/restic-password"; + }; +in +{ + options.backup = { + group = lib.mkOption { + default = null; + type = lib.types.nullOr (lib.types.attrsOf (lib.types.submodule { + options = { + paths = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = '' + Paths to backup + ''; + }; + }; + })); + }; + }; + + config = lib.mkIf (cfg.group != null) { + services.restic.backups = lib.concatMapAttrs + (group: groupCfg: { + ${group} = mkBackup group groupCfg.paths; + }) + cfg.group; + + age.secrets.backblaze-s3-backups.file = ../secrets/backblaze-s3-backups.age; + age.secrets.restic-password.file = ../secrets/restic-password.age; + }; +} diff --git a/common/default.nix b/common/default.nix index 5f78016..f7545a1 100644 --- a/common/default.nix +++ b/common/default.nix @@ -7,6 +7,7 @@ let in { imports = [ + ./backups.nix ./flakes.nix ./auto-update.nix ./shell.nix diff --git a/common/network/hosts.nix b/common/network/hosts.nix index 5fc2d10..c291298 100644 --- a/common/network/hosts.nix +++ b/common/network/hosts.nix @@ -1,12 +1,6 @@ { config, lib, ... }: -with builtins; - let - # TODO: remove when all systems are updated to new enough nixpkgs - concatMapAttrs = - f: with lib; flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ]; - system = (import ../ssh.nix).system; # hostnames that resolve on clearnet for LUKS unlocking @@ -57,7 +51,7 @@ in # prebuilt cmds for easy ssh LUKS unlock environment.shellAliases = - concatMapAttrs (host: addr: { "unlock-over-tor_${host}" = "torsocks ssh root@${addr}"; }) unlock-onion-hosts + lib.concatMapAttrs (host: addr: { "unlock-over-tor_${host}" = "torsocks ssh root@${addr}"; }) unlock-onion-hosts // - concatMapAttrs (host: addr: { "unlock_${host}" = "ssh root@${addr}"; }) unlock-clearnet-hosts; + lib.concatMapAttrs (host: addr: { "unlock_${host}" = "ssh root@${addr}"; }) unlock-clearnet-hosts; } diff --git a/common/network/tailscale.nix b/common/network/tailscale.nix index 6499641..fbb6127 100644 --- a/common/network/tailscale.nix +++ b/common/network/tailscale.nix @@ -11,7 +11,7 @@ in config.services.tailscale.enable = mkDefault (!config.boot.isContainer); # MagicDNS - config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" "100.100.100.100" ]; + config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" ]; config.networking.search = mkIf cfg.enable [ "koi-bebop.ts.net" ]; # exit node diff --git a/common/server/gitea.nix b/common/server/gitea.nix index 22a5d88..8b3e963 100644 --- a/common/server/gitea.nix +++ b/common/server/gitea.nix @@ -1,4 +1,4 @@ -{ lib, config, ... }: +{ lib, pkgs, config, ... }: let cfg = config.services.gitea; @@ -16,7 +16,7 @@ in rootUrl = "https://${cfg.hostname}/"; appName = cfg.hostname; # lfs.enable = true; - dump.enable = true; + # dump.enable = true; settings = { other = { SHOW_FOOTER_VERSION = false; @@ -30,8 +30,21 @@ in session = { COOKIE_SECURE = true; }; + mailer = { + ENABLED = true; + MAILER_TYPE = "sendmail"; + FROM = "do-not-reply@neet.dev"; + SENDMAIL_PATH = "/run/wrappers/bin/sendmail"; + SENDMAIL_ARGS = "--"; + }; }; }; + + # backups + backup.group."gitea".paths = [ + config.services.gitea.stateDir + ]; + services.nginx.enable = true; services.nginx.virtualHosts.${cfg.hostname} = { enableACME = true; diff --git a/common/server/mailserver.nix b/common/server/mailserver.nix index 1baa605..08723c0 100644 --- a/common/server/mailserver.nix +++ b/common/server/mailserver.nix @@ -82,5 +82,10 @@ in $config['smtp_pass'] = "%p"; ''; }; + + # backups + backup.group."email".paths = [ + config.mailserver.mailDirectory + ]; }; } diff --git a/common/server/nextcloud.nix b/common/server/nextcloud.nix index 09c5387..30129d9 100644 --- a/common/server/nextcloud.nix +++ b/common/server/nextcloud.nix @@ -20,6 +20,12 @@ in file = ../../secrets/nextcloud-pw.age; owner = "nextcloud"; }; + + # backups + backup.group."nextcloud".paths = [ + config.services.nextcloud.home + ]; + services.nginx.virtualHosts.${config.services.nextcloud.hostName} = { enableACME = true; forceSSL = true; diff --git a/common/server/samba.nix b/common/server/samba.nix index c3822a8..8f8c011 100644 --- a/common/server/samba.nix +++ b/common/server/samba.nix @@ -77,6 +77,13 @@ }; }; + # backups + backup.group."samba".paths = [ + config.services.samba.shares.googlebot.path + config.services.samba.shares.cris.path + "${config.services.samba.shares.public.path}/Regularly_Backed_Up" + ]; + # Windows discovery of samba server services.samba-wsdd = { enable = true; diff --git a/common/server/thelounge.nix b/common/server/thelounge.nix index 34f3e48..a149856 100644 --- a/common/server/thelounge.nix +++ b/common/server/thelounge.nix @@ -43,6 +43,10 @@ in }; }; + backup.group."thelounge".paths = [ + "/var/lib/thelounge/" + ]; + # the lounge client services.nginx.virtualHosts.${cfg.host} = { enableACME = true; diff --git a/flake.lock b/flake.lock index 371354e..d69aa99 100644 --- a/flake.lock +++ b/flake.lock @@ -215,7 +215,7 @@ "nixpkgs-hostapd-pr": { "flake": false, "locked": { - "narHash": "sha256-XwZgYqlPmqNU2vWl/xgeg6X15U2b3ln2KOVPY2yPwlI=", + "narHash": "sha256-1rGQKcB1jeRPc1n021ulyOVkA6L6xmNYKmeqQ94+iRc=", "type": "file", "url": "https://github.com/NixOS/nixpkgs/pull/222536.patch" }, diff --git a/machines/ponyo/configuration.nix b/machines/ponyo/configuration.nix index fc22a64..60871ed 100644 --- a/machines/ponyo/configuration.nix +++ b/machines/ponyo/configuration.nix @@ -52,6 +52,9 @@ file = ../../secrets/wolframalpha.age; owner = config.services.drastikbot.user; }; + backup.group."dailybot".paths = [ + config.services.drastikbot.dataDir + ]; # music radio vpn-container.enable = true; diff --git a/secrets/backblaze-s3-backups.age b/secrets/backblaze-s3-backups.age new file mode 100644 index 0000000000000000000000000000000000000000..8f089a8c0d65a8a4f98458178b3eab6307f3e6e7 GIT binary patch literal 1213 zcmZA0%j??&0KjoiBEg%W%<+SI@lyIr(j-lSY}huhrjI0ojmt@?z)d*Fxjd1!w9cBvM7u=caN=2MS40l@K7S~- zDQ;NUMnt9kvDUZyreAep(rF_)Tjv-f(av<(-3;iEAvDA)E5YnDfh-jPlqVXz1i)0q z?Ojvo{jMhv>|(bmmNsd0MRq&MR_nan+WbM&ij@~0YwNjW?!AsU(5JArM3k?N4SHai~NN^<1 zqYYit1Q{Nh+(4vIO;PMn;?u^~4v55f$6CWtL#gVth$D_i%S~Z4;KW)P3yKwT1Q|M} zN+PO1wMolWX3SV`Okm*+S{bDzE3iZn?^i)GSoNE|;>PN(ba=mJBg#zSO^iXun%0;c zD0Pq|%kotB*+w-TwnD`{wmgjcFk6cSCKx zJa7&z&m$He=Kg?Erzwp4D7ss>CeJJ?;KkeTJpJg^+mAD!!ROz5U;F3z%MV?cUH%>A3f1~IeyhVJ$>Wuo7T_Bjbh$busx$VpD#GBcT%n8moudY|8oz{sx|a!sD`QcLZ{ zG9$0Gu{(C6233w2WD+P#b+}Ept%qZ|INvBneA%#vlY0v7&eo>8R8viaPNvK{^(q@@ z>Sg2AUQw>?Qu3vFVKI;q7nFDEdAI}o|1@7#og_pM!LxUGyFq_?!i(GbU&WXA1`Qb=g*RJNf6b!}5_e`5Ji@UcnOD&TtC1Q=s1 zM9oa}odN_s$aT85)NO1@#MzRz{3(_)MO>-*Dg*sNvsI)O$dS;edbQNEp0g;ADA|?O z$<-zI;=$P?c41n=qCOGowbm`?Ky6SmX$L}<;dWBA(*cvmhl$B^(b47OMY0dra#rAR zgB=HeM0TYUMnq@tPvH4k;8|;|3k2aYEwhVy7AH90XPLY;#4x$mww<%YRJ7D7%04X0 zf>jEDyCT*Ezyg*$79*tzC9yv%g3~aZ@VvM0=}>^Q+KysHUM>k;FIl)X9mB6XcgMRz ze#pj^O7KVXT8lO*4ja_+BgNNOm@3&}tY2pH(*&#ugQ_ezbv8zn3%Tl0c8VJ`VoKH8 zuG@mq@P0-m9&I-AC_V7)F586qh2Ku$aYD0+!_hA^*pG){9=Jt-ND>e+e=oQW+?F9S z91c-8BkaRwkcQf(u`n8xmtV66+!wnwv=shkG$M{@%YF7&fAZEe)jFF z|2p^XfLDHcYAH|5f4;u;