Pull Backup with Restic to a QNAP NAS S3 store
This commit is contained in:
parent
8544eaafd9
commit
07a4308272
94
content/2023-11-06-restic.md
Normal file
94
content/2023-11-06-restic.md
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
+++
|
||||||
|
title = "Pull Backup with Restic to a QNAP NAS S3 store"
|
||||||
|
date = 2023-11-06
|
||||||
|
[taxonomies]
|
||||||
|
tags = [ "restic", "NixOS", "backup" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
Although [`restic`](https://restic.net/) is a really nice backup solution, it lacks the possibility to pull the files to
|
||||||
|
backup from a remote server, like rsync does over `ssh`, preventing any attacker to gain access to a secret.
|
||||||
|
This blog post shows some workarounds and does the backup to a QNAP NAS S3 store over an encrypted TLS connection.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
To pull the files, `rsync` is used. On the remote server a user `backup` is created with `.ssh/authorized_keys`:
|
||||||
|
|
||||||
|
```text,.ssh/authorized_keys
|
||||||
|
restrict,command="/run/wrappers/bin/rrsync -ro /" ssh-rsa AAAA[…]<a public ssh-key>
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `/run/wrappers/bin/rrsync` with the path to an s-bit wrapper only executable by user `backup`,
|
||||||
|
which sets the capabilities `cap_dac_read_search=+ep` and finally exec´s `rrsync`. `rrsync` will only allow
|
||||||
|
to read files, when called with `-ro`.
|
||||||
|
|
||||||
|
This enables the trusted internal machine to `rsync` all files from the remote machine.
|
||||||
|
The local mirror can now be backed up with `restic` from the internal machine. No secret on the remote machine gives an
|
||||||
|
attacker access to anything.
|
||||||
|
|
||||||
|
If you don't have the space for a local mirror, then you may use [`unpfs`](https://github.com/pfpacket/rust-9p),
|
||||||
|
which uses the 9p filesystem to mount the remote server. With ssh port forwarding
|
||||||
|
(also with a capability wrapper and restrict), this can be done encrypted.
|
||||||
|
The mount point can then be backed up with restic as usual.
|
||||||
|
This is way slower than using rsync over ssh,
|
||||||
|
but might be the only solution (although disk space is cheap nowadays).
|
||||||
|
|
||||||
|
The `rrsync` solution for NixOS looks like this for the remote machine:
|
||||||
|
```nix
|
||||||
|
{ ... } : {
|
||||||
|
# …
|
||||||
|
users.users.backup = {
|
||||||
|
shell = pkgs.bash;
|
||||||
|
isNormalUser = true;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"restrict,command=\"/run/wrappers/bin/rrsync -ro /\" ssh-rsa AAAAB[…]"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.wrappers.rrsync = {
|
||||||
|
source = "${pkgs.rrsync.out}/bin/rrsync";
|
||||||
|
owner = "backup";
|
||||||
|
group = "users";
|
||||||
|
permissions = "u=rwx,g=,o=";
|
||||||
|
capabilities = "cap_dac_read_search=+ep";
|
||||||
|
};
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and the `restic` solution for the local machine:
|
||||||
|
```nix
|
||||||
|
{ ... } : {
|
||||||
|
# …
|
||||||
|
services.restic.backups.xxx = {
|
||||||
|
repository = "s3:xxxxxxx.myqnapcloud.com:8081/backup";
|
||||||
|
environmentFile = "/var/lib/secrets/backup-s3";
|
||||||
|
passwordFile = "/var/lib/secrets/backup-pw";
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
FixedRandomDelay = true;
|
||||||
|
RandomizedDelaySec = "1h";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
paths = [ "/home/backup/xxx" ];
|
||||||
|
pruneOpts = [
|
||||||
|
"-g host,paths"
|
||||||
|
"--keep-daily 7"
|
||||||
|
"--keep-weekly 4"
|
||||||
|
"--keep-monthly 3"
|
||||||
|
"--keep-yearly 1"
|
||||||
|
];
|
||||||
|
backupPrepareCommand = ''
|
||||||
|
HOME=/root ${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh" --no-specials --no-devices --numeric-ids --delete-after --partial -axz backup@example.org:/{etc,var,home,root} /home/backup/xxx
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
For the above rsync, I was lazy and used `/root/.ssh/config` to specify the ssh config for the remote machine, like the ssh key.
|
||||||
|
|
||||||
|
As you can see, I am using my QNAP NAS as an S3 store. This is possible with the QNAP
|
||||||
|
[QuObjects](https://www.qnap.com/en/software/quobjects) app for free. You can get a LetsEncrypt cert for the QNAP,
|
||||||
|
enable virtual web servers on the QNAP and run the QuObjects server with the external `xxxxxxx.myqnapcloud.com` name.
|
||||||
|
That way, the backup channel to the QNAP is encrypted, even if it's all happening in your trusted home zone.
|
||||||
|
|
||||||
|
<!-- [<i class="fab fa-mastodon fa-normal"></i> Comment on Mastodon](https://floss.social/@backslash/111306835788566256) -->
|
Loading…
Reference in a new issue