restic / rest-server

Rest Server is a high performance HTTP server that implements restic's REST backend API.
BSD 2-Clause "Simplified" License
899 stars 139 forks source link

FR: add Host-level access control #248

Closed mirabilos closed 12 months ago

mirabilos commented 1 year ago

Output of rest-server --version

rest-server version rest-server 0.11.0 compiled with go1.17.6 on linux/amd64

What should rest-server do differently?

Add per-user Host-level access control: for each HTTP-level user, add the ability to provide a whitelist of Hosts they may see (to back up to, restore, inspect, etc).

What are you trying to do? What is your use case?

I have multiple servers backing up to the same repository to use deduplication, but not all of them are (yet) full-disc-encrypted. Since I need to use the same repository password to make use of deduplication, a root breach on one can be used to access all others’ data.

(On that topic, once this is implemented and/or once I will have converted all servers to FDE, how do I change it to achieve a secure state?)

Did rest-server help you today? Did it make you happy in any way?

I was very sceptical at first, especially because these things are implemented in issue9, but I’ve begun using it once I had more than one GNU/Linux box under me. I’ll have to find a solution for my BSD boxen for which there’s no issue9 port but even manually-triggered backups there are better than none (just rsync copies of actual user data), especially to save system re-setup time.

So, yes, it does help me (restic + rest-server). Danke, fd0!

wojas commented 12 months ago

Add per-user Host-level access control: for each HTTP-level user, add the ability to provide a whitelist of Hosts they may see (to back up to, restore, inspect, etc).

I would recommend always running production-level rest-server instance behind an HTTP server like nginx or caddy, which offer all kinds of extra features, including the ability to block by remote IP address.

I have multiple servers backing up to the same repository to use deduplication, but not all of them are (yet) full-disc-encrypted. Since I need to use the same repository password to make use of deduplication, a root breach on one can be used to access all others’ data.

If individual servers are not allowed to read data from other servers, do not give them access to the same repository.

Disk encryption will only help if someone steals the physical servers or manages to somehow get a copy of the disk images. Your IP blocking may help mitigate the impact in this specific scenario.

It does not protect you, however, if someone manages to gain remote access to one of the servers. In this case the attacker can access all data from all servers anyway.

PR #140 adds the ability to use multiple users to access the same repo. It has been open for a while, I guess I should update it. It would probably be a prerequisite for any non-global IP restrictions anyway.

mirabilos commented 12 months ago

wojas dixit:

Add per-user Host-level access control: for each HTTP-level user, add the ability to provide a whitelist of Hosts they may see (to back up to, restore, inspect, etc).

I would recommend always running production-level rest-server instance behind an HTTP server like nginx or caddy, which offer all kinds of extra features, including the ability to block by remote IP address.

Not relevant here, as this is about hosts not accessing (well, not enumerating probably) each others’ snapshots.

I have multiple servers backing up to the same repository to use deduplication, but not all of them are (yet) full-disc-encrypted. Since I need to use the same repository password to make use of deduplication, a root breach on one can be used to access all others’ data.

If individual servers are not allowed to read data other from other servers, do not give them access to the same repository.

That would break deduplication

Disk encryption will only help if someone steals the physical servers or manages to somehow get a copy of the disk images. Your IP blocking may help mitigate the impact in this specific scenario.

Huh, no?!

Hm okay, well it could, but I’d easier do that in the firewall than by putting an extra Apache in front of rest-server.

It does not protect you, however, if someone manages to gain remote access to one of the servers. In this case the attacker can access all data from all servers anyway.

Right; that’s the one I want to at least limit.

I want hosts unable to enumerate other hosts’ snapshots, and, ideally, unable to access other hosts’ data unless it is, via deduplication, also their own.

PR #140 adds the ability to use multiple users to access the same repo.

?!?!?! This already works. I’ve been using it in that setup (multiple users accessing one repo) since the beginning, over a year ago.

bye, //mirabilos -- Solange man keine schmutzigen Tricks macht, und ich meine wirklich schmutzige Tricks, wie bei einer doppelt verketteten Liste beide Pointer XORen und in nur einem Word speichern, funktioniert Boehm ganz hervorragend. -- Andreas Bogk über boehm-gc in d.a.s.r

MichaelEischer commented 12 months ago

Add per-user Host-level access control: for each HTTP-level user, add the ability to provide a whitelist of Hosts they may see (to back up to, restore, inspect, etc).

The Host concept from within a restic snapshot is not visible at all to the rest-server.

Since I need to use the same repository password to make use of deduplication, a root breach on one can be used to access all others’ data.

That's a fundamental limitation that cannot be solved at all at the rest-server side. Either the rest-server would have to become able to manage individual blobs uploaded by the clients (which would require a server-side that's somewhat related to that used by borgbackup and massive changes to restic) or restic would have to implement https://github.com/restic/restic/issues/187 together with some way to share blobs across different clients/encryption keys (no idea how that could be implemented, even more complex than the first option).

On that topic, once this is implemented and/or once I will have converted all servers to FDE, how do I change it to achieve a secure state?

In place reencryption is not supported. Thus, you'd have to create a new repository and copy the snapshots over. Or assume that the key files haven't been compromised and just change their password.

I was very sceptical at first, especially because these things are implemented in [...]

@mirabilos I'd like to remind you of https://github.com/restic/rest-server/pull/184#issuecomment-1101396703 .

mirabilos commented 12 months ago

Michael Eischer dixit:

Add per-user Host-level access control: for each HTTP-level user, add the ability to provide a whitelist of Hosts they may see (to back up to, restore, inspect, etc).

The Host concept from within a restic snapshot is not visible at all to the rest-server.

Oh! I didn’t know that.

Since I need to use the same repository password to make use of deduplication, a root breach on one can be used to access all others’ data.

That's a fundamental limitation that cannot be solved at all at the […]

OK, thanks for the detailed response.

https://github.com/restic/restic/issues/187 together with some way to share blobs across different clients/encryption keys (no idea how that

I thought (naïvely as seen above) that, while they use the same encryption key, access is still gated via rest-server where each host has its own .htaccess password, so even if they know the encryption key it can be made so that they can’t access different hosts’ snapshots (since rest-server knows the htaccess username of a connecting client so it might only need to add a mapping for which htaccess user may access what Hosts).

But (as above), it doesn’t know about Hosts, so, yes I can see how that isn’t going to be there with small effort.

On that topic, once this is implemented and/or once I will have converted all servers to FDE, how do I change it to achieve a secure state?

In place reencryption is not supported. Thus, you'd have to create a new repository and copy the snapshots over. Or assume that the key files haven't been compromised and just change their password.

Thank you. I find https://restic.readthedocs.io/en/stable/070_encryption.html rather lacking in explanation and what’s what, so:

Is this summary correct?

The 070_encryption page mentions it’s possible to add a key. But if I add one, it’s not usable to decrypt any existing snapshot, because it’s a separate encryption key, not a keyslot to the same encryption key like in LUKS?

I guess key passwd deletes the old file, so maybe hardlink it before, then use shred -u on the hardlink copy? I’ll try.

bye, //mirabilos -- (gnutls can also be used, but if you are compiling lynx for your own use, there is no reason to consider using that package) -- Thomas E. Dickey on the Lynx mailing list, about OpenSSL

MichaelEischer commented 11 months ago

The 070_encryption page mentions it’s possible to add a key. But if I add one, it’s not usable to decrypt any existing snapshot, because it’s a separate encryption key, not a keyslot to the same encryption key like in LUKS?

All keys in a repository contain the same masterkey, similar to the keyslots in LUKS. That is the password you pass to restic is used to decrypt the matching keyfile. A new key will therefore provide access to all snapshots.

mirabilos commented 11 months ago

Michael Eischer dixit:

add one, it’s not usable to decrypt any existing snapshot, because it’s a separate encryption key, not a keyslot to the same encryption key like in LUKS?

All keys in a repository contain the same masterkey, similar to the keyslots in LUKS. That is the password you pass to restic is used to decrypt the matching keyfile. A new key will therefore provide access to all snapshots.

Ah okay, thank you!

So, I would add a new one, then shred the old one.

bye, //mirabilos -- 15:41⎜<Lo-lan-do:#fusionforge> Somebody write a testsuite for helloworld :-)