From 2ca15ddaadd4f1823aed02ba931b5f4d471a052a Mon Sep 17 00:00:00 2001 From: emily Date: Fri, 8 Nov 2024 14:49:21 +0100 Subject: [PATCH] restic,florp: add backup --- .sops.yaml | 6 ++ config/hosts/florp/configuration.nix | 11 +++- config/hosts/lain/iso.nix | 1 + config/services/akkoma/default.nix | 10 +-- modules/restic/default.nix | 65 +++++++++++++++++++ .../zh3485.rsync.net/ssh_host_ed25519_key.pub | 1 + pkgs/update-nixfiles/update-nixfiles.sh | 5 +- secrets/restic/zh3485s1.yaml | 35 ++++++++++ 8 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 modules/restic/default.nix create mode 100644 modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub create mode 100644 secrets/restic/zh3485s1.yaml diff --git a/.sops.yaml b/.sops.yaml index fc9da64..bc78ba5 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -59,3 +59,9 @@ creation_rules: - *emily age: - *florp + - path_regex: secrets/restic/zh3485s1.yaml + key_groups: + - pgp: + - *emily + age: + - *florp diff --git a/config/hosts/florp/configuration.nix b/config/hosts/florp/configuration.nix index 4a7e62f..365cfd5 100644 --- a/config/hosts/florp/configuration.nix +++ b/config/hosts/florp/configuration.nix @@ -12,6 +12,15 @@ domain = lib.mkForce "social"; }; kyouma.nginx.defaultForbidden = "florp.social"; + + kyouma.restic = { + enable = true; + remoteUser = "zh3485s1"; + paths = [ + "/var/lib/akkoma" + "/var/lib/postgresql" + ]; + }; systemd.network.networks."98-eth-default" = { address = [ "2a0f:be01:0:100::171/128" @@ -19,7 +28,7 @@ }; services.postgresql.settings = { - max_connections = 30; + max_connections = 128; shared_buffers = "4GB"; effective_cache_size = "12GB"; maintenance_work_mem = "1GB"; diff --git a/config/hosts/lain/iso.nix b/config/hosts/lain/iso.nix index 69bfdbf..ac836a1 100644 --- a/config/hosts/lain/iso.nix +++ b/config/hosts/lain/iso.nix @@ -1,5 +1,6 @@ { lib, inputs, ... }: { imports = [ + inputs.sops-nix.nixosModules.sops "${inputs.nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix" ./configuration.nix ]; diff --git a/config/services/akkoma/default.nix b/config/services/akkoma/default.nix index 4baebfe..b340fc2 100644 --- a/config/services/akkoma/default.nix +++ b/config/services/akkoma/default.nix @@ -101,7 +101,6 @@ "solitary.social" "donotsta.re" "chaos.social" - "girldick.gay" ]; }; @@ -242,11 +241,12 @@ services.nginx = { clientMaxBodySize = "256m"; commonHttpConfig = '' - proxy_cache_path /var/cache/nginx/akkoma-media-cache - levels= keys_zone=akkoma_media_cache:32m max_size=32g - inactive=1y use_temp_path=off; + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/err.log warn; - access_log off; + proxy_cache_path /var/cache/nginx/akkoma-media-cache + levels= keys_zone=akkoma_media_cache:32m max_size=64g + inactive=1y use_temp_path=off; ''; }; kyouma.nginx.virtualHosts = let diff --git a/modules/restic/default.nix b/modules/restic/default.nix new file mode 100644 index 0000000..226001f --- /dev/null +++ b/modules/restic/default.nix @@ -0,0 +1,65 @@ +{ config, lib, pkgs, ... }: let + cfg = config.kyouma.restic; +in { + options.kyouma.restic = let + inherit (lib) mkOption types; + in { + enable = lib.mkEnableOption "Enable restic backup"; + paths = mkOption { + description = "paths to backup"; + type = with types; listOf path; + default = []; + }; + pruneOpts = mkOption { + description = "paths to backup"; + type = with types; listOf str; + default = [ + "--keep-hourly 24" + "--keep-daily 14" + "--keep-weekly 8" + "--keep-monthly 12" + ]; + }; + remote = mkOption { + description = "restic remote to use"; + type = types.nonEmptyStr; + default = "zh3485.rsync.net"; + }; + remoteUser = mkOption { + description = "remote ssh user"; + type = types.nonEmptyStr; + default = ""; + }; + user = mkOption { + description = "user who runs the backup job"; + type = types.nonEmptyStr; + default = "root"; + }; + repo = mkOption { + description = "restic repo"; + type = types.nonEmptyStr; + default = "${config.networking.hostName}-backup"; + }; + }; + config = lib.mkIf cfg.enable { + sops.secrets."restic/${cfg.remoteUser}/password" = { + sopsFile = ../../secrets/restic/${cfg.remoteUser}.yaml; + }; + sops.secrets."restic/${cfg.remoteUser}/id_ed25519" = { + sopsFile = ../../secrets/restic/${cfg.remoteUser}.yaml; + }; + + services.restic.backups."${config.networking.hostName}-${cfg.remote}" = { + inherit (cfg) paths user pruneOpts; + initialize = true; + repository = "sftp:${cfg.remoteUser}@${cfg.remote}:${cfg.repo}"; + passwordFile = config.sops.secrets."restic/${cfg.remoteUser}/password".path; + extraOptions = let + knownHost = pkgs.writeText "${cfg.remote}-known-host" (builtins.readFile ./${cfg.remote}/ssh_host_ed25519_key.pub); + sshKey = config.sops.secrets."restic/${cfg.remoteUser}/id_ed25519".path; + in [ + "sftp.command='ssh ${cfg.remoteUser}@${cfg.remote} -i ${sshKey} -o UserKnownHostsFile=${knownHost} -s sftp'" + ]; + }; + }; +} diff --git a/modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub b/modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub new file mode 100644 index 0000000..a4fe26e --- /dev/null +++ b/modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub @@ -0,0 +1 @@ +zh3485.rsync.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd diff --git a/pkgs/update-nixfiles/update-nixfiles.sh b/pkgs/update-nixfiles/update-nixfiles.sh index f2c8169..1bec09d 100644 --- a/pkgs/update-nixfiles/update-nixfiles.sh +++ b/pkgs/update-nixfiles/update-nixfiles.sh @@ -6,7 +6,6 @@ BRANCH="update-inputs-$(date +%Y-%m-%d-%H-%M)" HYDRA_URL="https://hydra.kyouma.net" JOBSET_URL="${HYDRA_URL}/jobset/nixfiles/update-inputs" ROOT="$(mktemp -d)" -START_TIME="$(date +%s)" gitin () { git -C "${ROOT}/nixfiles" "$@" @@ -24,6 +23,8 @@ merge_theirs () { test_build () { local last_error local build_jobs + local start_time + start_time="$(date +%s)" build_jobs="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}/latest-eval" | jq -r ".builds | .[]")" for build in ${build_jobs}; do @@ -44,7 +45,7 @@ test_build () { done last_error="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}" | jq -r ".errortime")" - [[ $last_error -gt $START_TIME ]] && + [[ $last_error -gt $start_time ]] && echo "Evaluation error encountered at $(date +%Y-%m-%d-%H:%M:%S --date="@${last_error}")" && exit 1 } diff --git a/secrets/restic/zh3485s1.yaml b/secrets/restic/zh3485s1.yaml new file mode 100644 index 0000000..7ec39ce --- /dev/null +++ b/secrets/restic/zh3485s1.yaml @@ -0,0 +1,35 @@ +restic: + zh3485s1: + password: ENC[AES256_GCM,data:lDDSSqUH3pewpMA+6SNwGwRz95MBjeaD6I3RWUQNBFXsw/W9RoIY85AcRXxCl7CW,iv:NFF6uCs2FolMe9cgPkoAFmbWdXG2SuVRtoOyQXouEAU=,tag:UeC49xFwFkMh0Wi8p9reFw==,type:str] + id_ed25519: ENC[AES256_GCM,data:fe2CAKWSrEOvEPZgGhbigw+DEnDUGtTXEj7nuGaH5enMGDvd7QtRlDYLkM+g9zKrRJ46e2nM6btUZVqqx4rJiUbjJ5B/cBzb259CTxKGgHeMj/cYXPypamIEKFwUrloxzrgxH5JIOoUvj9Ny1P1UPIB//B5Z1Uunqmdqd2XoiAtDwZ/hvyuOfdFyUkKmOnCdF4pheMRXZ6Z51N4f09OIwuZ/xC4LQYAVB2lyycOgrvefPA5YYabMd23yEXn6v/BiP1TWbSInTHvz6Rii2WYqYO3ORCfi1pvWe15kSrTsT9zYRzLvZi5TD+4FMhLmIttZB2OXK7X+h6cHtej7X+v6HKhMKHNJhukRUP7DpcZ0+ArBEdw2j+H7C4q8NdR9rk4we7WpdQlY7tGpJvEzSis+P/Jph/tkzx6xXpKiOeOAXgQUS41qcAy7gmZj7CdsulerUHcfDy4a0y1OEuDmoYW420cGGYOCB9BlvYQbaDhyv5AMSL8sMZfm7mX5qXliE7ZQc20ggKoY2MKH6RjnT8pQhMBWo/NW13PPBDIL,iv:1+aopW183ir5XHMKcDons24A/E61mLuyJGrQTRpPXdE=,tag:s1w+HZdktM0H9FUrz097Cw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age18vc8rcmczlt3r0ee7jr9s8l3yrkthu8wtypt08eh0eskpkw3dg6qxs7t3t + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQeWpKYktzVE1tMkpGU1c5 + akZZdlBkeFQyUmUrOHZxTGE2V1FUVmV3cG5VCmZvTG1JTS9SUTk1aVl6TnBPQ1Fh + clRDTmQzQUJxWlYyV2dmVXNyTDJ2K0kKLS0tIHA3S0dsQzRxRWF4RFdSSzh1aXI5 + ZFQvWFhZTndubkxaRVh3YXl0V25ZcUEK0/wV9i01kRkphrseSBqAL9f8tUlUtJDO + PUZL2Em/QjNEnXJaxxR612ONA94ptK9bsqzRJV5RtGqDwd+oAnr13Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-08T13:41:02Z" + mac: ENC[AES256_GCM,data:tMatUcv/jbvQ1URp6DrUyuiB9+rgCCdOxEVcM0NBiV5P9DGWE1hWytky4yPE9nFUOWLI7m4nTSEXHuT4yT3LkBd1Ndzhm5wQ0NEAVnZ6Sj7YOQI5CS1q95sviJBv57PBkaajHDNeSJX2hEQeR4qJFUR4fu0hIwadyzeunP/kfKE=,iv:gXRAg4cN43ocQMZm0lL8AnrbDtK+TKGchWpd/TYhnjA=,tag:+HqYuDWjoTdv+CWrJmuwxA==,type:str] + pgp: + - created_at: "2024-11-08T13:31:55Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4D1GtNSlou/HkSAQdALVqRZ2qzjR86mEE/MHAR5H3gmIukchY/NSvGg1Ggfmsw + uZhnl5puGOO579ItHXbk+BYwBS2koL7jyhnX8E9zmM3d3SZHwzx0mk79fr2jLFj6 + 0l4BLrhhcpUtzfje4/SeTgWFRIA68ON/PUTmW2Lgclh9OpQfbbousFS/JMvvdHaT + /3uJEww5MKMPlqWqK7w7z6iwIITRKH0vzQoIZ3hVcDKtKOJrJ/1bWcJorFsazxvT + =KZPf + -----END PGP MESSAGE----- + fp: B04F01A7A98A13020C39B4A68AB7B773A214ACE5 + unencrypted_suffix: _unencrypted + version: 3.9.1