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