borgbackup / borg

Deduplicating archiver with compression and authenticated encryption.
https://www.borgbackup.org/
Other
11.21k stars 743 forks source link

Borg serve read-only mode #4756

Open scruloose opened 5 years ago

scruloose commented 5 years ago

Have you checked borgbackup docs, FAQ, and open Github issues?

Yes

Is this a BUG / ISSUE report or a QUESTION?

Feature request

System information. For client/server mode post info for both machines.

Your borg version (borg -V).

1.1.9 (on both client and server)

Operating system (distribution) and version.

Debian Buster (server) and Debian Bullseye (client)

Hardware / network configuration, and filesystems used.

Borg serve, using the restricted ssh configuration described in the docs under "Deployment → Hosting repositories". Ext4 filesystem on both sides. The repo is un-encrypted (authentication only mode, no passphrase) but it resides on a LUKS encrypted drive.

How much data is handled by borg?

Currently, a few kB for preliminary testing.

Full borg commandline that lead to the problem (leave away excludes and passwords)

It's not a specific borg commandline that's the problem; it's a surprising absence in the borg serve options.

Describe the problem you're observing.

I have set up my client system so that a backup process can run as root, using a root-owned ssh key (password protected and accessed through keychain), in order to do full-system backups. So far, so good. I would like to add entries to the server-side authorized_keys file to allow read-only access to the repo for individual users on the client machine, using their own individual ssh keys. This way, users could easily borg diff to track down changes, list and extract files belonging to them, borg mount the archive and browse to a file they accidentally deleted, etc. The file/directory permissions inside the archive should protect against users reading files they aren't allowed to (UID mismatch is a non-issue since these are users on the same system that's reflected in the repository), and there would be no risk of accidentally or maliciously corrupting the archive (barring an exploit that compromises borg serve).

I have looked at the discussion on issue #1772, and while append-only mode is better than full access, it leaves the door open to some potential headaches (especially, as I understand it, in append-only mode you can add delete operations to the queue, and then the next automatic backup that runs with full access and includes a prune will commit those deletions.)

I see there's a reference in the old changelogs for version 0.8 that says "Support access of read only repositories", but I found no indication anywhere in the docs of a way to actually grant read-only access to a repository. I assume (perhaps naively) that a --read-only option to borg serve wouldn't be excessively hard to implement, and if it's already in there I'd appreciate any help on where to find / how to use that.

ThomasWaldmann commented 5 years ago

If you give users repo access, they can read all the files in the repo (not only "files belonging to them"). Are you sure you want to do that?

scruloose commented 5 years ago

Well, I won't say I'm sure, but here's my thinking:

  1. I was assuming that borg mount would enforce the ownership and permissions of files in the repository, and also that attempting to extract a file to which you don't have read access would fail, so the user would be able to see the existence and filenames of everything, (which I grant could be undesirable), but not the actual contents. I admit that I didn't test this assumption, though, so I may well be wrong.
  2. My use-case is essentially single-user desktop systems being backed up each to its own user account on a home NAS, so realistically the read-only protection would facilitate allowing my wife's and my regular user accounts to mount and browse the backups of our own respective machines without risk of a careless mistake or a ransomware infection wrecking things, and there's nothing in each repo that needs to be kept secret from that user. So even if the above assumption is wrong, it seems to me that read-only access would still be nice to have as a convenience feature.
ThomasWaldmann commented 5 years ago
  1. The security must happen server side as the code on the client side is under user control.

Or, the user who gets repo access permission must run trusted code and must be different than a potentially malicious user accessing files via borg mount.

The FUSE security check situation changed in a recent borg version and should be ok now (but was less great before that).

  1. We have "append only" repos, but they work a bit differently from what you envision.

If you want to protect against malware wrecking your backups, i guess read-only just for normal users and read-write for root could go seriously wrong if the malware acquires root permissions.

scruloose commented 5 years ago

Yeah, the "append-only" repo could work for my purposes if it really meant that appending stuff to the repo was all the client can do. But according to issue #1772 "append-only" allows queueing all sorts of operations including deleting or overwriting the existing data in the repo, and those changes will be committed for real as soon as a scheduled "prune" job runs. As far as I'm concerned, that's roughly equivalent to unrestricted read/write access.

I make some effort to protect my backups even against an attacker who gains root privileges on a client machine (root's ssh key has a strong passphrase, the key is loaded in keychain to allow automated backups to use it, and root's login shell in /etc/passwd is a wrapper script that unloads keychain before launching bash). Ultimately you're right, though, that things could go seriously wrong if any malware or attacker gains root access. However, the only way to really avoid that risk is to do true pull backups from a server that doesn't accept any commands from the client, period. Since Borg doesn't support that (and for the record I think Borg's single biggest shortcoming is the lack of a "reverse server" mode, where the backup server could connect to root@client, pull stuff according to a server-side includes/excludes list, with all the deduplicating bandwidth optimizations, and then hang up)... I think that the "if the attacker gains root on the client" battle is already lost and doesn't have any direct relevance to the question of allowing read-only access to a non-root user with a different ssh key.

Does that make sense?

ThomasWaldmann commented 5 years ago

Yeah, borg does not solve the problem of deciding whether logical repo contents are like you want them to be.

And as soon as you switch off append-only and write to the repo (e.g. with borg prune), the physical contents will be like the logical contents (plus whatever prune does).

There already were some requests about disallowing borg delete and borg prune, but the server side does not know what high-level ops the client is doing, it is only seeing low-level ops. So that is not possible.

But your request is basically about disallowing some low-level ops (PUT, DELETE, COMMIT) and only allowing GET. I'll have a look into that.

scruloose commented 5 years ago

Awesome. I hope it proves straightforward to implement! ;-)

And just as a general idea: would it make sense to designate operations as to what kind of access they actually need/imply? (And designate high-level operations as to what low-level operations they need to perform.) In theory, that should enable sorting users into "full read-write access", "append but not alter existing data", and "read only" just by assigning them to a ready-to-go group of allowed operations. (With "users" referring to different public keys in ~/.ssh/authorized_keys`, of course.) This sounds like a lot of work, but (I believe) it's work that could be picked away at gradually, without affecting the program's behaviour along the way...

amaramrahul commented 5 years ago

Just curious if with the current low-level calls, would it be possible to disable logically deleting and pruning of older archives when accessed via borg serve (i.e. any modification of older archives)? Because in my case, I know that a client would generally not perform any modification of older archives. It just creates new backups every day. If I need to modify an older archive for some reason, I would do it directly on backup machine (need to check if could I do this) or maybe re-run borg serve with the ability for pruning and deleting explicitly. Apologies if this is a bit repetitive. I have gone through multiple tickets but couldn't get a clear answer for this.

ThomasWaldmann commented 3 years ago

Just noticed that for repo-monitoring (like listing archives and checking if there are recent backups) a read-only enforcement within borg serve would be also nice to have, so that the monitoring server does not need to get r/w (and not append-only) access to all repos it monitors.

NicoHood commented 2 years ago

What is the current status of this?

ThomasWaldmann commented 2 years ago

No news here.

bof commented 1 year ago

For what it's worth, while I've been playing around with borg (2.0.0b4) evaluating what it can and cannot do, I've been testing a borg serve setup where the whole server side tree was readonly on the filesystem level - actually a readonly bind mount of the actual writable one.

That worked quite nicely for listing archives, and accessing their content, including borg mount - when giving the borg client command the --bypass-lock argument.

Furthermore, with borg mount run as root on the client with -o allow_other option, individual users on the client get access to read whatever the permissions of the backup allow them to read.

I don't think this is usable as-is in a permanent way, as bypassing the lock probably will make the client mightily confused as soon as any further change to the repository happens. But it does demonstrate IMO that a hypothetical borg serve --readonly option could be kind of viable.

debuglevel commented 1 year ago

borg serve --read-only would also be a nice feature for some disaster recovery use cases: I just created a restricted SSH key with borg-1.2 --serve --append-only --restrict-to-path ... and will put that into our disaster recovery documentation.

Using this SSH key, they should be able to recover any repository but should be prevented from unrecoverable damage. For now, they still can do some things using this SSH key which I do not really want (e.g. add further archives, mark archives as deleted, ...).