bragi backup config #28

Merged
Gonne merged 5 commits from Gonne/nixConfig:bragi into main 2024-03-30 19:10:30 +00:00
6 changed files with 273 additions and 1 deletions

View file

@ -1,6 +1,6 @@
keys:
- &nerf age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
- &gonne age1xv5rfxkxg9jyqx5jg2j82cxv7w7ep4a3795p4yl5fuqf38f3m3eqfnefju
- &gonne age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
- &nyarlathotep age1s99d0vlj5qlm287n98jratql5fypvjrxxal0k5jl2aw9dcc8kyvqw5yyt4
- &bragi age1lqvgpmlemyg9095ujck64u59ma29656zs7a4yxgz4s6u5cld2ccss69jwe

View file

@ -0,0 +1,39 @@
backupKey: ENC[AES256_GCM,data:PBdeV6uQ/Jg9xk7HXylyDKCBdny/XRflF752arUZAnUvmVv4yiSwOY9ua3tH1BDpddiql1aNJqmfatZOB3JKB2mHnyeSt7L0B81zuIFpxJOdsnGACviH6sUfsC5ogkGRhLKynf5Ghz/6xanthyK6euIpAAu05wDWcseg4y8k5rdFhL7rasmOMi0oVLN54Psmyf9vahfX6BNGBHQA1qJyeaI5iDLI+6gh7dtOXjTd4pHX8T9PEYpGnOBMHvaaVA2r7z27iUJSKqzzSB9B/rm01tI6LTG/yfQU+TKlWFU2iIodCG7eJ2qe+exvxOlEj9At/UI/Kd+dNSHcffLDUxVcstthOOP0TUdHkPCTC8BEJtAAexUBqSv+LTOPfJeAbIw3QhEpfeyZOpw2FY1qstQ/G0+1sDF8762uJu9v1amx4+4e8NEiSa/dtdnQAKFiEswk+5nqRSKQJOH3w0tHr9NRhhS775lUtUX4DW0xN42QeABM0xg56qJPxPNif3K2ovPX3BTSSZnQ0EZzuxployu1MyJxpcBT+6qa8l/h,iv:ZdivBorDtIyBOs7XSg/DHjReG+T6/exeS8ziA7ms7FM=,tag:gcIXgpyd2UeQV3APqCCxMg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaR2dRc3NPeUwwaHdCL25V
RHNaWU9xRUw5dDlaOG5hczVlNm5UR01QUEVNClJsVFRBWU85Z0JuV1l3MDdvd1F2
RS9CcXhuNEJWdEE1cktXYjF3RW9wUDQKLS0tIHk3MURmWlJNanVZaHlUR3R2UEZG
K2JxOHpNY2hsTysrWjNLajFKQkxuNHcKaFMvnDt9a3HsnbP1Q/i4ifRIXFcXYn8z
YyOho0hSmWZNhTbltmuVKjvCNgt9ONVRW93uRDDoju8Odps0qwwvuA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMM1NCbHdFZDJvYjJjcmZ6
bUFjSG5OUEdydS9pTkNHRjFKb3gvWll0Q0RVCk56ZnhDa0NGeUNhVVdDZENieDFW
Q0xSNXhYQXZSVnI3WlRzUjhxOXRyM2sKLS0tIGhnVWJaRG4vSGpUcnQ5SFVFT3VQ
YUFzTlNLSE9CbW9oYTFsY0tpTE4vZTQKjurd87tDH8z58pAGJyVXRAu8Q2+k7e4G
zOGZhm5DpSmFv2O2fqXgBg8nT5wrPKQDFvcDh1P+a0753tUTbUttIA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1lqvgpmlemyg9095ujck64u59ma29656zs7a4yxgz4s6u5cld2ccss69jwe
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlWmlwS0E5TytFdEpxN09U
Y3k0SDhnM2h5Rnh1bXQ2czA5bWt1Mkk3aUFFCmtwT2ZmN0IweGdOYURWNDVHcWtH
R3lRaFRkcWYzb2g4NWNFQU5WOXZZaGMKLS0tIHpWNnNvVUNucE5MQ1cxQWl6Qm1x
NUZDVnJORXF1NGlyNUkzOGl2REFHdmsK18k9UfOmtFSep6mZcSp6di7SjvrBXgGp
oWtLehp1UFEHCgaU5YxlYhtkrrOhb8ykFb1on+kmzrloaHqyvks7Aw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-03-21T16:38:08Z"
mac: ENC[AES256_GCM,data:kEVWd988Ia6T8v3w0slQhM0lh78VhnP8qJNa6IZg0NF2B0JQbFRnQNbUfvG9Rf4mkAR/O9PD+r6HR+b3LCwzb/Ok/eD4/M3+oPaEx/JnoHrzF/1N29VEAvBHjQgw6DL05toqu5G03UDcDUFGc111AeRsexhONQRHJx3zqWyWGy4=,iv:T5Pkhl3vhSAIoKkC3r3VQn3tC4t04WxvAZDQ4PMvD84=,tag:h0/aB91SFr5q0Or5daxWUQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -0,0 +1,15 @@
{
imports = [
./hardware-configuration.nix
../../roles
../../roles/hardware.nix
./network.nix
../../modules/borgbackup.nix
];
services.mathebau-borgbackup.enable = true;
# System configuration here
networking.hostName = "bragi";
system.stateVersion = "23.11";
}

View file

@ -0,0 +1,32 @@
{lib, ...}: {
fileSystems."/" = {
device = "root";
fsType = "tmpfs";
options = ["size=2G" "mode=755"];
};
fileSystems."/persist" = {
device = "/dev/disk/by-label/nixos";
Outdated
Review

Is addressing by label actually nicer than by uuid? It seems to work at least.

Is addressing by label actually nicer than by uuid? It seems to work at least.
fsType = "btrfs";
options = ["subvol=persist"];
neededForBoot = true;
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "ext4";
};
fileSystems."/nix" = {
device = "/dev/disk/by-label/nixos";
fsType = "btrfs";
options = ["subvol=nix"];
};
fileSystems."/var/lib/backups" = {
device = "/dev/disk/by-label/backups";
fsType = "btrfs";
};
swapDevices = [{device = "/dev/disk/by-label/swap";}];
boot.loader.grub.device = "/dev/disk/by-id/wwn-0x5000c5003891662c";
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -0,0 +1,15 @@
# We sohuld put that config somewhere in roles and give it a parameter or something,
# everyone gets the same nameserver and the same prefixLength and address vs defaultGateway alsways
# depend on the same thing
{
networking = {
interfaces.enp0s25.ipv4.addresses = [
{
address = "192.168.1.11";
prefixLength = 24;
}
];
defaultGateway = "192.168.1.137";
nameservers = ["130.83.2.22" "130.83.56.60" "130.83.22.60" "130.82.22.63"];
};
}

View file

@ -0,0 +1,171 @@
{
config,
lib,
pkgs,
...
}: let
inherit
(lib)
mkIf
mkEnableOption
;
cfg = config.services.mathebau-borgbackup;
in {
imports = [];
options.services.mathebau-borgbackup = {
enable = mkEnableOption "mathebau borgbackup service";
};
config = mkIf cfg.enable {
services.borgbackup = {
# repos are made available at ssh://borg@hostname and served according to the presented ssh-key
Outdated
Review

Perhaps we want to create these repos by a function that only takes the name and the ssh-key. Not sure if that is worth it.

Perhaps we want to create these repos by a function that only takes the name and the ssh-key. Not sure if that is worth it.
Gonne marked this conversation as resolved Outdated
Outdated
Review

where exactly do these keys come from? Can we automatize this? so we either just need to name the machine here, or completely automatically by virtue of beeing a machine?

Of course we need a a mechanism like this for legacy non nix machines

where exactly do these keys come from? Can we automatize this? so we either just need to name the machine here, or completely automatically by virtue of beeing a machine? Of course we need a a mechanism like this for legacy non nix machines
Outdated
Review

See also #28 (comment)

This can probably be automated (?) but currently no Nix machine needs backups.
Thus I would like to postpone it.

See also https://gitea.mathebau.de/Fachschaft/nixConfig/pulls/28#issuecomment-565 This can probably be automated (?) but currently no Nix machine needs backups. Thus I would like to postpone it.
Outdated
Review

Can we then put a comment like:

„Congratulations, you are the first person to make backups from a nixos machine.
Your won the task of automatizing this endeavor, so in future we don't need to hand copy any
ssh keys anymore“

Btw. I don't think this is too trivial, as the public keys are needed while config build time, but the secret keys should probably never leave the machines.

One way would be pre-generated key-pairs that are deployed through sops.
(But then we should make sure to use dedicated keys for this task.)

Can we then put a comment like: „Congratulations, you are the first person to make backups from a nixos machine. Your won the task of automatizing this endeavor, so in future we don't need to hand copy any ssh keys anymore“ Btw. I don't think this is too trivial, as the public keys are needed while config build time, but the secret keys should probably never leave the machines. One way would be pre-generated key-pairs that are deployed through sops. (But then we should make sure to use dedicated keys for this task.)
# If you think about adding keys of nix machines:
# Congratulations, you are the first person to make backups from a nixos machine.
# Your won the task of automatizing this endeavor, so in future we don't need to hand copy any
# ssh keys anymore.
repos = {
aphoom-zhah = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA8pI6uinXezAMH4vG2yEbu/yOYU5vXcsZN74tYgV+Wj Aphoom-Zhah Backup"
];
path = "/var/lib/backups/aphoom-zhah";
# subrepos are allowed because each vm creates at least one repo below this filepath and yibb-tstll even more
allowSubRepos = true;
};
azathoth = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGBEwllQ77ktoirXX6dJ6ET8TfK4lzq0aaq+X4rrX2Vk Azathoth Backup"
];
path = "/var/lib/backups/azathoth";
allowSubRepos = true;
};
cthulhu = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSJl1MvabUADTdOCgufsBzn1tIIpxMq4iDcYZsaW1lV Cthulhu Backup"
];
path = "/var/lib/backups/cthulhu";
allowSubRepos = true;
};
dagon = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJaTBennwqT9eB43gVD1nM1os3dMPZ8RWwIKPEjqMK5V Dagon Backup"
];
path = "/var/lib/backups/dagon";
allowSubRepos = true;
};
eihort = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHLoDxtY4Tp6NKxLt9oHmWT6w4UpU6eA1TnPU2Ut83BN Eihort Backup"
];
path = "/var/lib/backups/eihort";
allowSubRepos = true;
};
fsaccount = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG+Y7fQTYdIWHehrKdk92CaJ0AisEux4OrS4nIyMstU4 FS Account Backup"
];
path = "/var/lib/backups/fsaccount";
allowSubRepos = true;
};
hastur = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILeDvTyOUdIPARatX0PPhHgrV1gjERWLt2Twa8E2GETb Hastur Backupsystem"
];
path = "/var/lib/backups/hastur";
allowSubRepos = true;
};
ithaqua = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJmBf8cz3FTDdeuxWbp1MO2yPT5rvH8ZIGUzfogjpXi Ithaqua Backup"
];
path = "/var/lib/backups/ithaqua";
allowSubRepos = true;
};
sanctamariamaterdei = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9Le5OI4ympQ0mQKYHmxgxGF598rzpD5VVpWK1mGfd8 Sanctamariamaterdei Backupsystem"
];
path = "/var/lib/backups/sanctamariamaterdei";
allowSubRepos = true;
};
tsathoggua = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKS9/1lFOhv+3sNuGcysM3TYh2xRrjMeAZX3K7CBx0QW Tsathoggua Backup"
];
path = "/var/lib/backups/tsathoggua";
allowSubRepos = true;
};
uvhash = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB8DjIqgFgmYhQnTLpbqL0r7xBPb8TPy6SO5RhQ31OGj Uvhash Backup"
];
path = "/var/lib/backups/uvhash";
allowSubRepos = true;
};
yibb-tstll = {
authorizedKeysAppendOnly = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINlnGOV58Ks9lu+WTI4F7QAHtDrJq2jY8ZocITZG8K0+ Yibb-Tstll Backup"
];
path = "/var/lib/backups/yibb-tstll";
allowSubRepos = true;
};
};
# Configure backup of files on the department's fs account:
# This job first copies the files to the local account 'fsaccount' in tmpfs
Outdated
Review

Did I get something wrong?
It seams the fsaccount backups are under /home/fsaccount
owned by fsaccount:users

While all the machines ones are under /var/lib/backups probably owned
by some backup system user. Why is this set up this way, or am I reading this wrong?

Did I get something wrong? It seams the fsaccount backups are under `/home/fsaccount` owned by `fsaccount:users` While all the machines ones are under `/var/lib/backups` probably owned by some backup system user. Why is this set up this way, or am I reading this wrong?
# and then takes a regular backup of the mirrored folder.
# See also https://borgbackup.readthedocs.io/en/stable/deployment/pull-backup.html
# which does not work due to missing permissions.
jobs.fsaccount = {
preHook = ''
Gonne marked this conversation as resolved
Review

I would put a small note here, that encryption would mean either putting the key next to the backup or human interaction.

I would put a small note here, that encryption would mean either putting the key next to the backup or human interaction.
mkdir -p /home/fsaccount/sicherung # Create if it does not exist
${pkgs.rsync}/bin/rsync -e 'ssh -i /run/secrets/backupKey' -r fachschaft@gw1.mathematik.tu-darmstadt.de:/home/fachschaft/* /home/fsaccount/sicherung
'';
Review

Why is this here, what does it do? I also don't really get it from the Borg documentation

BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no (or =yes)

For “Warning: Attempting to access a previously unknown unencrypted repository”

Why is this here, what does it do? I also don't really get it from the Borg documentation > BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no (or =yes) > > For “Warning: Attempting to access a previously unknown unencrypted repository”
paths = "/home/fsaccount/sicherung";
Outdated
Review

By creating the folder sicherung via systemd-tmpfiles we could restrict this to /home/fsaccount/sicherung.
I don't know if this restriction is worth the increased complexity.

By creating the folder `sicherung` via [systemd-tmpfiles](https://search.nixos.org/options?show=systemd.tmpfiles.rules) we could restrict this to `/home/fsaccount/sicherung`. I don't know if this restriction is worth the increased complexity.
encryption.mode = "none"; # Otherwise the key is next to the backup or we have human interaction.
environment = {
BORG_RSH = "ssh -i /run/secrets/backupKey";
# “Borg ensures that backups are not created on random drives that just happen to contain a Borg repository.”
# https://borgbackup.readthedocs.io/en/stable/deployment/automated-local.html
# We don't want this in order to not need to persist borg cache and simplify new deployments.
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
};
repo = "borg@localhost:fsaccount";
startAt = "daily";
user = "fsaccount";
group = "users";
readWritePaths = ["/home/fsaccount"];
};
};
Gonne marked this conversation as resolved Outdated
Outdated
Review

Why is this a normal user, do we plan to log in as this one, or is it just there to pull the fs account?

Why is this a normal user, do we plan to log in as this one, or is it just there to pull the fs account?
Outdated
Review

Login is not necessary, so we can transform it to a system user.

Login is not necessary, so we can transform it to a system user.
# Extra user for FS account backup
users.users = {
fsaccount = {
description = "FS Account backup";
isSystemUser = true;
home = "/home/fsaccount";
createHome = true;
group = "users";
};
};
environment.persistence.${config.impermanence.name} = {
users.fsaccount.files = [
{
file = ".ssh/known_hosts";
parentDirectory = {
mode = "u=rwx,g=,o=";
user = "fsaccount";
group = "users";
};
}
];
};
sops.secrets.backupKey = {
sopsFile = ../machines/bragi/backupKey.yaml;
owner = config.users.users.fsaccount.name;
inherit (config.users.users.fsaccount) group;
mode = "0400";
};
};
}