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 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCTy$al;&FINZ(@OSb^ z%{NU7&dTz!F!C@83iUP#v?z}7F-cGJFAnnXGOVi1_l^wCwBXXVba68-tS}3XFf~Z> zPj)QN&v%aW(e`&OG7k$3sWi(B3pGk~HPA2dh(xz7H>upB!coD?B`m;2-@hWzN8i-5 z#HYy8-#tAm%Do^X$k;E-Gp`~t$I#t9sIc5U$dfCpI3>x@IX&Dp+bPS~jBa%tWu!u&|P(^lWt7QhWm=^V1aq%)-45Lp-XS&2zI1D+0n@va<7nEiLm3O)4Tv z6Qin9L&~C(bBl|83=FuOQk(-l{7l^QydvCFvI||j3ydQw3_ZPk0zCY~%-xJCo!l$4 z!wiajP0G=2Gjj|v(oa`N)h;wH^p8k4FK`Mhsz|NM4R$rpGYRvrNH(!>HH<2Csw&7x zbc+lv2{YkJPYpJ8Pt&*Xur&8FsdTMywXn=Ctt^f(4$KZIG%+nLGxx4c3@bGbbW2CK ztFAGuXcHz3oyz+XGqJ)^)QJ<1^2Gs?XvGASzAyr{@DvZTPnH6=i%ubiuH z_e?dO&fQ{e+YF@_?+x}iB6(${rKI=f(~lR)o_*FU-Ss!FiNV&V>0o_rd*apA;<~MQ z9g%u^eMkGFR_>Zu8PvIG?&DbpR%I1g=sF1hy1BHb*>dmw{4);}Y^Cb=*sXi_b5q0I k+7;135l(kGzR$n=V=3GEU;7n5@3pm-Etj3Xsrgbk0GctI%>V!Z literal 0 HcmV?d00001 diff --git a/secrets/restic-password.age b/secrets/restic-password.age new file mode 100644 index 0000000000000000000000000000000000000000..b2501bc9dd318fc35960ab3ab7f8817d7cf7a213 GIT binary patch literal 1076 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCTy$al;&FIR{#cFD{N zFY(Ltbjr_4@vulqsz^5T%`NtKDabW(4+(UvC^3lia`rR{4dl|c2+7Dy)Xs7C&-PC8 z%yZ314RWl^3n?*8&Mq|#)i2F=%PtA=2`nl%E=RX5H>upB!coDuyf`Vm&@I?JJux`k zyVNPEurMvm-Ot21B&wt^Aks6-)i*FNDk3L8-GIy0%{U{^%_p*`!qUmt-N(|^sIsss z#XZWv(IBPF(!|ds$FL-*Ai~w7&;;E!qeP>~jB*A4Ed4yo{5)Tuvh=Wmu!Sw_q-@acMRK7d;=r%(-qQv+)};DjDr#j@+zIYz4P=9yxhwS(t=#_Oe^z@ zElpEW0=+Fw4I}&wBDt!+u4 z%?d009nt+}<``n6pRN#E=$#T-?3h~RSQKng79JRu8SZ186Ydk{o}KAa={{`hf~1 z!KS7WX|5&3&i=)YhKb(#<*AP0j^VyW-WmSo=|0|7IsTrJ<(6)q#(`W_RTk-2Io4tWScqq8HbpbhUb|_283i3c@_mmnnn~DhFEZg`jq-blvNa41{qd4ndT>1 zgqHgn6r{OVL=^_42j{wnndfDhSvcoMx>X=v1kgng48Y?+$)bzb94u0!#(mCvV