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 0000000..8f089a8 Binary files /dev/null and b/secrets/backblaze-s3-backups.age differ diff --git a/secrets/restic-password.age b/secrets/restic-password.age new file mode 100644 index 0000000..b2501bc Binary files /dev/null and b/secrets/restic-password.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 97f1384..045bbb0 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -1,27 +1,39 @@ let keys = import ../common/ssh.nix; system = keys.system; - systems = keys.systems; - users = keys.users; - all = users ++ systems; + systemsList = keys.systems; + usersList = keys.users; + all = usersList ++ systemsList; wireless = [ system.router - ] ++ users; + ] ++ usersList; in { # TODO: Minimum necessary access to keys + + # email "email-pw.age".publicKeys = all; - "iodine.age".publicKeys = all; - "nextcloud-pw.age".publicKeys = all; - "pia-login.conf".publicKeys = all; "sasl_relay_passwd.age".publicKeys = all; - "searx.age".publicKeys = all; + + # vpn + "iodine.age".publicKeys = all; + "pia-login.conf".publicKeys = all; + + # cloud + "nextcloud-pw.age".publicKeys = all; "smb-secrets.age".publicKeys = all; + + # services + "searx.age".publicKeys = all; "spotifyd.age".publicKeys = all; "wolframalpha.age".publicKeys = all; # hostapd "hostapd-pw-experimental-tower.age".publicKeys = wireless; "hostapd-pw-CXNK00BF9176.age".publicKeys = wireless; + + # backups + "backblaze-s3-backups.age".publicKeys = all; + "restic-password.age".publicKeys = all; }