ZFS zfs send | zfs recv: security considerations

Hi,

I have set up zfs send | zfs recv replication as an unprivileged user. The purpose is to have an off-site backup process that is a) fast, and b) secure, in the sense that a successful cryptolocker attack on the primary backup would be partitioned off by the dint of append-only replication to the secondary.

I will describe my config below, and would be grateful for a critical review with respect to the threat model above.

On the receive side:
Code:
[root@RECEIVE ~]$ uname -a
FreeBSD RECEIVE.fqdn 13.1-RELEASE-p6 FreeBSD 13.1-RELEASE-p6 GENERIC amd64

[root@RECEIVE ~]$ id REPLICATOR
uid=5555(REPLICATOR) gid=5555(REPLICATOR) groups=5555(REPLICATOR)

[root@RECEIVE ~]$ ls -lah /tank/RECEIVE/
total 59
drwxr-xr-x  2 REPLICATOR  REPLICATOR      3B Feb 24 03:49 .
drwxr-xr-x  3 root  wheel     3B Feb 24 00:01 ..

[root@RECEIVE ~]$ zfs allow tank/RECEIVE
---- Permissions on tank/RECEIVE ----------------------------------------
Local+Descendent permissions:
    group REPLICATOR compression,create,dedup,mount,mountpoint,receive,snapshot

I am purposefully trying to avoid allowing mount,mountpoint and the attendant vfs.usermount=1. In my setup, I forcefully set the mountpoint to legacy so that an attacker could not craft a zfs stream that would then be mounted in a sensitive place on the receiver. Perhaps this is overkill; vfs.usermount seems to require the mountpoint to be owned by the user.

Unfortunately, in my tests it seems that both mount,mountpoint are necessary even if that attribute is stripped. Does anyone know why?

For completeness, the following works on the sender:
Code:
zfs send -R tank/SOURCE@test-replication | ssh REPLICATOR@RECEIVE.fqdn "zfs recv -v -o mountpoint=legacy tank/RECEIVE"

Best
leveche
 
Did you try receiving without mounting?
-u File system that is associated with the received stream is not mounted.
like this
Code:
zfs send -R tank/SOURCE@test-replication | ssh REPLICATOR@RECEIVE.fqdn "zfs recv -v -u tank/RECEIVE"
 
Thanks skeletor!

I hadn't thought of that - but alas, when I tried it doesn't seem to make a difference. I still get permission denied unless the permissions on the receive dataset include mountpoint,mount.

Was worth a try though.
 
Back
Top