restic backups

This commit is contained in:
Zuckerberg 2023-04-08 21:25:55 -06:00
parent f68a4f4431
commit 378cf47683
14 changed files with 121 additions and 20 deletions

56
common/backups.nix Normal file
View File

@ -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;
};
}

View File

@ -7,6 +7,7 @@ let
in in
{ {
imports = [ imports = [
./backups.nix
./flakes.nix ./flakes.nix
./auto-update.nix ./auto-update.nix
./shell.nix ./shell.nix

View File

@ -1,12 +1,6 @@
{ config, lib, ... }: { config, lib, ... }:
with builtins;
let 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; system = (import ../ssh.nix).system;
# hostnames that resolve on clearnet for LUKS unlocking # hostnames that resolve on clearnet for LUKS unlocking
@ -57,7 +51,7 @@ in
# prebuilt cmds for easy ssh LUKS unlock # prebuilt cmds for easy ssh LUKS unlock
environment.shellAliases = 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;
} }

View File

@ -11,7 +11,7 @@ in
config.services.tailscale.enable = mkDefault (!config.boot.isContainer); config.services.tailscale.enable = mkDefault (!config.boot.isContainer);
# MagicDNS # 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" ]; config.networking.search = mkIf cfg.enable [ "koi-bebop.ts.net" ];
# exit node # exit node

View File

@ -1,4 +1,4 @@
{ lib, config, ... }: { lib, pkgs, config, ... }:
let let
cfg = config.services.gitea; cfg = config.services.gitea;
@ -16,7 +16,7 @@ in
rootUrl = "https://${cfg.hostname}/"; rootUrl = "https://${cfg.hostname}/";
appName = cfg.hostname; appName = cfg.hostname;
# lfs.enable = true; # lfs.enable = true;
dump.enable = true; # dump.enable = true;
settings = { settings = {
other = { other = {
SHOW_FOOTER_VERSION = false; SHOW_FOOTER_VERSION = false;
@ -30,8 +30,21 @@ in
session = { session = {
COOKIE_SECURE = true; 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.enable = true;
services.nginx.virtualHosts.${cfg.hostname} = { services.nginx.virtualHosts.${cfg.hostname} = {
enableACME = true; enableACME = true;

View File

@ -82,5 +82,10 @@ in
$config['smtp_pass'] = "%p"; $config['smtp_pass'] = "%p";
''; '';
}; };
# backups
backup.group."email".paths = [
config.mailserver.mailDirectory
];
}; };
} }

View File

@ -20,6 +20,12 @@ in
file = ../../secrets/nextcloud-pw.age; file = ../../secrets/nextcloud-pw.age;
owner = "nextcloud"; owner = "nextcloud";
}; };
# backups
backup.group."nextcloud".paths = [
config.services.nextcloud.home
];
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = { services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;

View File

@ -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 # Windows discovery of samba server
services.samba-wsdd = { services.samba-wsdd = {
enable = true; enable = true;

View File

@ -43,6 +43,10 @@ in
}; };
}; };
backup.group."thelounge".paths = [
"/var/lib/thelounge/"
];
# the lounge client # the lounge client
services.nginx.virtualHosts.${cfg.host} = { services.nginx.virtualHosts.${cfg.host} = {
enableACME = true; enableACME = true;

2
flake.lock generated
View File

@ -215,7 +215,7 @@
"nixpkgs-hostapd-pr": { "nixpkgs-hostapd-pr": {
"flake": false, "flake": false,
"locked": { "locked": {
"narHash": "sha256-XwZgYqlPmqNU2vWl/xgeg6X15U2b3ln2KOVPY2yPwlI=", "narHash": "sha256-1rGQKcB1jeRPc1n021ulyOVkA6L6xmNYKmeqQ94+iRc=",
"type": "file", "type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/222536.patch" "url": "https://github.com/NixOS/nixpkgs/pull/222536.patch"
}, },

View File

@ -52,6 +52,9 @@
file = ../../secrets/wolframalpha.age; file = ../../secrets/wolframalpha.age;
owner = config.services.drastikbot.user; owner = config.services.drastikbot.user;
}; };
backup.group."dailybot".paths = [
config.services.drastikbot.dataDir
];
# music radio # music radio
vpn-container.enable = true; vpn-container.enable = true;

Binary file not shown.

BIN
secrets/restic-password.age Normal file

Binary file not shown.

View File

@ -1,27 +1,39 @@
let let
keys = import ../common/ssh.nix; keys = import ../common/ssh.nix;
system = keys.system; system = keys.system;
systems = keys.systems; systemsList = keys.systems;
users = keys.users; usersList = keys.users;
all = users ++ systems; all = usersList ++ systemsList;
wireless = [ wireless = [
system.router system.router
] ++ users; ] ++ usersList;
in in
{ {
# TODO: Minimum necessary access to keys # TODO: Minimum necessary access to keys
# email
"email-pw.age".publicKeys = all; "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; "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; "smb-secrets.age".publicKeys = all;
# services
"searx.age".publicKeys = all;
"spotifyd.age".publicKeys = all; "spotifyd.age".publicKeys = all;
"wolframalpha.age".publicKeys = all; "wolframalpha.age".publicKeys = all;
# hostapd # hostapd
"hostapd-pw-experimental-tower.age".publicKeys = wireless; "hostapd-pw-experimental-tower.age".publicKeys = wireless;
"hostapd-pw-CXNK00BF9176.age".publicKeys = wireless; "hostapd-pw-CXNK00BF9176.age".publicKeys = wireless;
# backups
"backblaze-s3-backups.age".publicKeys = all;
"restic-password.age".publicKeys = all;
} }