jimsalterjrs / sanoid

These are policy-driven snapshot management and replication tools which use OpenZFS for underlying next-gen storage. (Btrfs support plans are shelved unless and until btrfs becomes reliable.)
http://www.openoid.net/products/
GNU General Public License v3.0
3.07k stars 300 forks source link

RFC: change --no-privilege-elevation to be syncoid's default behavior #740

Open jimsalterjrs opened 2 years ago

jimsalterjrs commented 2 years ago

Now that we've removed explicit rollbacks and made it easier to use ZFS delegation for unprivileged replication, syncoid's currently-default detection of non-root execution coupled with attempts to use sudo really shouldn't be the default anymore.

I don't want to actually remove the ability to use sudo for privilege elevation entirely, but I would like to make it non-standard with an --elevate argument, and (at Allan Jude's suggestion) probably pair it with an --elevate-cmd option that lets people use alternate methods to sudo like doas.

I'm putting this RFC up now to both serve as notice that the standard behavior will be changing in the future, and allow anybody who objects to say their piece.

In the meantime, the proper way to handle replication IS with zfs delegation:

root@recvbox:~# zfs allow recvuser receive,create,mount

root@sendbox:~# zfs allow senduser send,hold

After which the following works with no elevation necessary, and no non-standard privileges:

recvuser@recvbox:~$ syncoid -r --no-privilege-elevation --no-sync-snap senduser@sendbox:pool/ds pool/ds

We'll give this RFC a week or two before making any further changes in trunk. Please comment here and/or spread the word if you know people who might need to comment on this change! Thanks.

chirayudesai commented 2 years ago

Semi-related: bookmark creation fails without privilege elevation.

Any ideas on what to allow / how to make that work?

CRITICAL ERROR: zfs bookmark .. failed: 256 at /usr/bin/syncoid line 854. version 2.1.0

jimsalterjrs commented 2 years ago

zfs allow username bookmark poolname/datasetname should do the trick on that one.

TopherIsSwell commented 2 years ago

I think this is an excellent change. @jimsalterjrs , What is the process for breaking changes like this? For those that are relying on the current default behavior, will there be a deprecation notice for a version or two? So when a non-root user zfs receives without the --no-privilege-elevation it prints a deprecation warning? I'll be tracking this change personally, but I'm curious what process you use for this and similar breaking changes, as I rely on this program for things important to me (and yes, I realize that's my problem, not yours, I just wanted your stance to help me adjust my personal risk management decisions).

rlaager commented 7 months ago

It seems the "destroy" permission is required as well. Otherwise, I get: cannot destroy snapshots: permission denied

jonathonwiebe commented 6 months ago

as a non-root user, mount is restricted and fails on the first backup, but no error on subsequent execution: syncoid --no-privilege-elevation user@server:tank/path tank-other/backups/path INFO: Sending oldest full snapshot tank/path@autosnap_2024-02-17_22:53:11_monthly (~ 218.6 GB) to new target filesystem: 218GiB 0:26:16 [ 142MiB/s] [===========================================>] 100% cannot mount '/tank-other/backups/path': failed to create mountpoint: Permission denied ...failed: 256 at /usr/sbin/syncoid line 492.

from the openZFS docs: Delegations are supported under Linux with the exception of mount, unmount, mountpoint, canmount, rename, and share. These permissions cannot be delegated because the Linux mount(8) command restricts modifications of the global namespace to the root user.

jimsalterjrs commented 6 months ago

It seems the "destroy" permission is required as well. Otherwise, I get: cannot destroy snapshots: permission denied

"Destroy" permissions are required for syncoid if you're using sync snaps. If you use --no-sync-snaps, you don't need the destroy permission.

jimsalterjrs commented 6 months ago

as a non-root user, mount is restricted and fails on the first backup, but no error on subsequent execution: syncoid --no-privilege-elevation user@server:tank/path tank-other/backups/path INFO: Sending oldest full snapshot tank/path@autosnap_2024-02-17_22:53:11_monthly (~ 218.6 GB) to new target filesystem: 218GiB 0:26:16 [ 142MiB/s] [===========================================>] 100% cannot mount '/tank-other/backups/path': failed to create mountpoint: Permission denied ...failed: 256 at /usr/sbin/syncoid line 492.

from the openZFS docs: Delegations are supported under Linux with the exception of mount, unmount, mountpoint, canmount, rename, and share. These permissions cannot be delegated because the Linux mount(8) command restricts modifications of the global namespace to the root user.

You probably only got an error the first time because you either manually mounted them yourself afterward, or did a zfs set mountpoint=none on them. Either option prevents syncoid from trying to mount the datasets in later runs.

jonathonwiebe commented 6 months ago

Should I split this into a separate issue? No manual mount, no zfs set mountpoint. One command executed after the other, with the zfs list prior to running:


NAME                                USED  AVAIL     REFER  MOUNTPOINT
tank                    21.2T  10.4T      349K  /tank
tank/backups            3.66T  10.4T      279K  /tank/backups
tank/backups/files       278G  10.4T      277G  /tank/backups/files
tank/backups/nextcloud  1.28T  10.4T     1.28T  /tank/backups/nextcloud

notroot@test-server:~$ syncoid --no-privilege-elevation notroot@10.0.10.31:tank-other/vm-images tank/backups/vm-images
INFO: Sending oldest full snapshot tank-other/vm-images@autosnap_2024-02-17_22:53:11_monthly (~ 6304.6 GB) to new target filesystem:
6.17TiB 11:29:11 [ 156MiB/s] [===============================================================================================================================================================>] 100%
cannot mount '/tank/backups/vm-images': failed to create mountpoint: Permission denied
CRITICAL ERROR: ssh     -S /tmp/syncoid-notroot@10.0.10.31-1708636137 notroot@10.0.10.31 ' zfs send  '"'"'tank-other/vm-images'"'"'@'"'"'autosnap_2024-02-17_22:53:11_monthly'"'"' | lzop  | mbuffer  -q -s 128k -m 16M 2>/dev/null' | mbuffer  -q -s 128k -m 16M 2>/dev/null | lzop -dfc | pv -p -t -e -r -b -s 6769542859328 |  zfs receive  -s -F 'tank/backups/vm-images' failed: 256 at /usr/sbin/syncoid line 492.
notroot@test-server:~$ syncoid --no-privilege-elevation notroot@10.0.10.31:tank-other/vm-images tank/backups/vm-images
Sending incremental tank-other/vm-images@autosnap_2024-02-17_22:53:11_monthly ... syncoid_test-server_2024-02-23:14:23:02-GMT00:00 (~ 16.5 GB):
16.9GiB 0:03:31 [81.9MiB/s] [=================================================================================================================================================================] 102%
notroot@test-server:~$```
phreaker0 commented 6 months ago

@jonathonwiebe this is not a syncoid issue. Like @jimsalterjrs said on Linux you will need root permission for mounting. If you run zfs mount -a manually on the target host as root (in this example the local one), the new dataset will be mounted and following syncoid runs will run without errors because no mounting is needed anymore.