bragi backup config #28
|
@ -1,6 +1,6 @@
|
|||
keys:
|
||||
- &nerf age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
|
||||
- &gonne age1xv5rfxkxg9jyqx5jg2j82cxv7w7ep4a3795p4yl5fuqf38f3m3eqfnefju
|
||||
- &gonne age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
|
||||
|
||||
- &nyarlathotep age1s99d0vlj5qlm287n98jratql5fypvjrxxal0k5jl2aw9dcc8kyvqw5yyt4
|
||||
- &bragi age1lqvgpmlemyg9095ujck64u59ma29656zs7a4yxgz4s6u5cld2ccss69jwe
|
||||
|
|
39
nixos/machines/bragi/backupKey.yaml
Normal 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
|
15
nixos/machines/bragi/configuration.nix
Normal 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";
|
||||
}
|
32
nixos/machines/bragi/hardware-configuration.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{lib, ...}: {
|
||||
fileSystems."/" = {
|
||||
device = "root";
|
||||
fsType = "tmpfs";
|
||||
options = ["size=2G" "mode=755"];
|
||||
};
|
||||
fileSystems."/persist" = {
|
||||
device = "/dev/disk/by-label/nixos";
|
||||
|
||||
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";
|
||||
}
|
15
nixos/machines/bragi/network.nix
Normal 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"];
|
||||
};
|
||||
}
|
171
nixos/modules/borgbackup.nix
Normal 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
|
||||
Gonne
commented
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
nerf
commented
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
Gonne
commented
See also #28 (comment) This can probably be automated (?) but currently no Nix machine needs backups. 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.
nerf
commented
Can we then put a comment like: „Congratulations, you are the first person to make backups from a nixos machine. 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. 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
|
||||
nerf
commented
Did I get something wrong? While all the machines ones are under 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
nerf
commented
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
|
||||
'';
|
||||
nerf
commented
Why is this here, what does it do? I also don't really get it from the Borg documentation
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";
|
||||
Gonne
commented
By creating the folder 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
nerf
commented
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?
Gonne
commented
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";
|
||||
};
|
||||
};
|
||||
}
|
Is addressing by label actually nicer than by uuid? It seems to work at least.