25.6 ZFS 委托管理
用户级 ZFS 管理
ZFS 允许非特权用户进行管理操作,这一机制称为 ZFS 委托管理(ZFS delegation)。
自 FreeBSD 14.1 以降(请参阅发行说明,由 此变更 实现),bsdinstall(8) 使用的工具 adduser(8) 会在用户主目录的父目录位于 ZFS 数据集上时自动为用户主目录创建一个 ZFS 数据集(例如,当 /home 是 ZFS 数据集时,/home/xxx 也会是独立的数据集)。adduser 的参数 -Z 可以禁用这一行为。此外,adduser 现已支持为非特权用户的 ZFS 主目录启用加密功能。
基础的用户级 ZFS 管理
首先介绍非特权用户的 ZFS 数据集。
我们首先在安装系统时,创建了两个普通用户“aria2”和“safreya”。
列出系统中所有 ZFS 文件系统及其属性:
% zfs list
NAME USED AVAIL REFER MOUNTPOINT
zroot 53.7G 396G 96K /zroot
zroot/ROOT 12.8G 396G 96K none
zroot/ROOT/14.1-RELEASE-p3_2024-09-17_194642 8K 396G 11.6G /
zroot/ROOT/default 12.8G 396G 11.9G /
zroot/aria2 187M 396G 187M /usr/local/data/aria2
zroot/home 7.74G 396G 96K /home
zroot/home/aria2 128K 396G 128K /home/aria2 # 请注意此行
zroot/home/safreya 7.74G 396G 7.70G /home/safreya # 请注意此行
zroot/jails 3.12G 396G 3.12G /usr/jails
zroot/sec 28.5G 396G 28.5G /usr/local/data/sec
zroot/tmp 102M 396G 102M /tmp
zroot/usr 1.34G 396G 96K /usr
zroot/usr/ports 1.34G 396G 1.34G /usr/ports
zroot/usr/src 96K 396G 96K /usr/src
zroot/var 1.58M 396G 96K /var
zroot/var/audit 96K 396G 96K /var/audit
zroot/var/crash 96K 396G 96K /var/crash
zroot/var/log 1.02M 396G 1.02M /var/log
zroot/var/mail 168K 396G 168K /var/mail
zroot/var/tmp 120K 396G 120K /var/tmp其中:
即,在创建用户时,系统已默认为用户 aria2 和 safreya 分别创建了各自独立的数据集 zroot/home/aria2 和 zroot/home/safreya。
接下来,分别查看一下两个数据集上的用户权限。
可以看到,系统在创建用户时,会默认为其数据集授予 create、destroy、mount 和 snapshot 四项权限。
所以,对于这两个数据集,普通用户亦可使用快照功能:
再来看 create、destroy 和 mount 权限:
以 root 用户执行以下命令,将 vfs.usermount 设置为 1,以允许非 root 用户挂载文件系统:
可以看到,创建(create)和销毁(destroy)权限可以正常使用,而挂载(mount)权限需要通过开启内核参数 vfs.usermount 来允许用户级挂载。
至此,用户级 ZFS 管理的基本需求已经满足。但仔细观察会发现 rollback 权限默认不可用,需要由 root 用户为普通用户授权该权限。
将 zroot/home/safreya 文件系统回滚到 snap1 快照状态:
以 root 用户授予 safreya 用户对 zroot/home/safreya 文件系统执行回滚操作的权限:
用户级 ZFS 加密功能
在 FreeBSD 14.1 中,若要在用户级使用 ZFS 加密功能,必须为用户授予特定权限。
授权用户 safreya 对 zroot/home/safreya 文件系统执行密钥管理和加密操作:
显示 zroot/home/safreya 文件系统的当前权限授权设置:
change-key、load-key、keyformat、keylocation 和 encryption 这五项权限属性用于 ZFS 的加密功能。
创建启用加密的 ZFS 数据集 zroot/home/safreya/secret,并将密码用作密钥格式:
查看加密情况:
查看 mounted 属性,加密数据集创建即挂载,现在创建一个文件,然后卸载加密数据集:
卸载加密数据集时必须同时卸载其密钥;挂载加密数据集时也必须先加载密钥:
注意
无论数据集是否挂载,
destroy子命令都可以成功销毁数据集,因为destroy权限默认已授予用户,因此如果操作的人不是该用户本人,仍可能删除数据集——即出现“我得不到的,就毁灭”的情况。切记,“授权”是为普通用户授予代理权限,使其在操作授权的数据集时拥有类似 root 的权限,无需输入密码。因此,在授予权限时应综合考虑,合理限制授权范围和权限属性,例如禁用
destroy权限属性等。
撤销用户 safreya 对 zroot/home/safreya 文件系统的销毁权限:
显示 zroot/home/safreya 文件系统的当前权限授权设置:
此处,zroot/home/safreya/secret 继承了 zroot/home/safreya 的权限属性,因此授权或取消授权操作仅针对 zroot/home/safreya,对 zroot/home/safreya/secret 的权限不会生效。操作后属性保持不变,因为 ZFS 不支持“动态继承刷新”:子数据集只会在“创建时”继承父数据集的委托权限,之后父数据集的授权或反授权变更,不会自动向下同步到已存在的子数据集。这种授权是“静态继承设计”,目的是防止父级权限变更意外破坏子数据集的既有管理策略,需要显式、逐级授权或回收。
adduser 与用户主目录加密
adduser 与用户主目录加密adduser 命令中可以直接使用加密的用户主目录数据集,但默认给出的权限不足,一经卸载就无法由普通用户直接挂载。
查看 zroot/home/test 文件系统的当前权限授权设置:
卸载数据集和密钥:
切换到普通用户 test 挂载尝试:
Permission denied 表示权限不足,访问被拒绝。
参考文献
FreeBSD 手册
OpenZFS Encryption Arrives on FreeBSD,说明了 GELI 加密和 zfs 加密的异同点
Merge OpenZFS support in to HEAD,FreeBSD 13.0 才转到了 OpenZFS
最后更新于