本章介绍如何使用委托管理来允许非特权用户执行 ZFS 管理任务。
本章包含以下各节:
通过 ZFS 委托管理,可向特定用户、组或每个人分配精确的权限。支持两种类型的委托权限:
可以显式委托各个权限,如 create、destroy、mount、snapshot 等。
可以定义称为权限集的权限组。以后可以更新权限集,并且权限集的所有使用者都会自动获得更改。权限集以 @ 符号开头,长度不能超出 64 个字符。在 @ 符号之后,集名称中的其余字符与标准的 ZFS 文件系统名称具有同样的限制。
ZFS 委托管理可提供与 RBAC 安全模型类似的功能。ZFS 委托在管理 ZFS 存储池和文件系统方面具有以下优点:
迁移 ZFS 存储池时,权限跟随存储池。
提供动态继承性,以便您可以控制权限通过文件系统传播的方式。
可进行配置,以便只有文件系统的创建者可以销毁该文件系统。
可向特定文件系统委托权限。新创建的文件系统可以自动获得权限。
提供简单的 NFS 管理。例如,具有显式权限的用户可以在适当的 .zfs/snapshot 目录中通过 NFS 创建快照。
可考虑使用委托管理来分配 ZFS 任务。有关使用 RBAC 来管理常规 Oracle Solaris 管理任务的信息,请参见《系统管理指南:安全性服务》中的第 III 部分, “角色、权限配置文件和权限”。
使用池的 delegation 属性控制委托管理功能。例如:
# zpool get delegation users NAME PROPERTY VALUE SOURCE users delegation on default # zpool set delegation=off users # zpool get delegation users NAME PROPERTY VALUE SOURCE users delegation off local |
缺省情况下,delegation 属性处于启用状态。
可以使用 zfs allow 命令通过以下方式将 ZFS 数据集的权限委托给非超级用户:
可将各个权限委托给用户、组或每个人。
可将各权限的组作为权限集委托给用户、组或每个人。
可将权限以本地方式仅委托给当前数据集,或委托给当前数据集的所有后代。
下表介绍了可以委托的操作以及执行委托操作所需要的所有相关权限。
权限(子命令) |
说明 |
相关性 |
---|---|---|
allow |
将您拥有的权限委托给其他用户的权限。 |
还必须具有正在允许的权限。 |
clone |
克隆数据集的任何快照的权限。 |
还必须在原始文件系统中具有 create 权限和 mount 权限。 |
create |
创建后代数据集的权限。 |
还必须具有 mount 权限。 |
destroy |
销毁数据集的权限。 |
还必须具有 mount 权限。 |
挂载 |
挂载和取消挂载数据集以及创建和销毁卷设备链接的权限。 | |
promote |
将克隆提升为数据集的权限。 |
还必须在原始文件系统中具有 mount 权限和 promote 权限。 |
receive |
使用 zfs receive 命令创建后代文件系统的权限。 |
还必须具有 mount 权限和 create 权限。 |
rename |
重命名数据集的权限。 |
还必须在新父级中具有 create 权限和 mount 权限。 |
rollback |
回滚快照的权限。 | |
send |
发送快照流的权限。 | |
share |
共享和取消共享数据集的权限。 | |
快照 |
创建数据集快照的权限。 |
您可以委托下面的一组权限,但权限可能只限于访问、读取或更改权限:
groupquota
groupused
userprop
userquota
userused
此外,还可向非超级用户委托以下 ZFS 属性的管理:
aclinherit
aclmode
atime
canmount
casesensitivity
checksum
compression
copies
devices
exec
mountpoint
nbmand
normalization
primarycache
quota
readonly
recordsize
refreservation
reservation
secondarycache
setuid
shareiscsi
sharenfs
sharesmb
snapdir
utf8only
version
volblocksize
volsize
vscan
xattr
zoned
其中有些属性只能在创建数据集时设置。有关这些属性的说明,请参见ZFS 属性介绍。
zfs allow -[ldugecs] everyone|user|group[,...] perm|@setname,...] filesystem| volume |
下面的 zfs allow 语法(以粗体显示)标识将权限委托给的对象:
zfs allow [-uge]|user|group|everyone [,...] filesystem | volume |
可以按逗号分隔的列表形式指定多个实体。如果未指定 -uge 选项,则优先将该参数解释为关键字 everyone,然后解释为用户名,最后解释为组名。要指定名为 "everyone" 的用户或组,请使用 -u 或 -g 选项。要将同名的组指定为用户,请使用 -g 选项。-c 选项可委托创建时权限。
以下 zfs allow 语法(以粗体显示)标识权限和权限集的指定方式:
zfs allow [-s] ... perm|@setname [,...] filesystem | volume |
可以按逗号分隔的列表形式指定多个权限。权限名与 ZFS 子命令和属性相同。有关更多信息,请参见上一节。
可以将权限聚合到权限集中,并由 -s 选项来标识。其他 zfs allow 命令可将权限集用于指定的文件系统及其后代。可以对权限集进行动态评估,因此对权限集的更改可立即更新。权限集与 ZFS 文件系统遵循相同的命名要求,但名称必须以 at 符号 (@) 开头,且长度不能超过 64 个字符。
下面的 zfs allow 语法(以粗体显示)标识权限的委托方式:
zfs allow [-ld] ... ... filesystem | volume |
-l 选项指示权限允许用于指定的数据集,但不允许用于该数据集的后代,除非同时指定 -d 选项。-d 选项指示权限允许用于后代数据集,但不允许用于该数据集,除非同时指定 -l 选项。如果两个选项均未指定,则权限允许用于文件系统或卷及其所有后代。
使用 zfs unallow 命令可以删除以前委托的权限。
例如,假定您按如下方式委托了 create、destroy、mount 和 snapshot 权限:
# zfs allow cindys create,destroy,mount,snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot ------------------------------------------------------------- |
要删除这些权限,请使用以下语法:
# zfs unallow cindys tank/cindys # zfs allow tank/cindys |
在为单个用户委托 create 和 mount 权限时,必须确保该用户对底层挂载点拥有权限。
例如,要向用户 marks 委托对 tank 文件系统的 create 和 mount 权限,需要先设置权限:
# chmod A+user:marks:add_subdirectory:fd:allow /tank |
然后,使用 zfs allow 命令委托 create、destroy 和 mount 权限。例如:
# zfs allow marks create,destroy,mount tank |
现在,用户 marks 可以在 tank 文件系统中创建其自己的文件系统。例如:
# su marks marks$ zfs create tank/marks marks$ ^D # su lp $ zfs create tank/lp cannot create 'tank/lp': permission denied |
以下示例说明如何设置文件系统,以使 staff 组中的每个人都可以在 tank 文件系统中创建和挂载文件系统,还可以销毁其自己的文件系统。但是,staff 组成员不能销毁其他任何人的文件系统。
# zfs allow staff create,mount tank # zfs allow -c create,destroy tank # zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) create,destroy Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- # su cindys cindys% zfs create tank/cindys cindys% exit # su marks marks% zfs create tank/marks/data marks% exit cindys% zfs destroy tank/marks/data cannot destroy 'tank/mark': permission denied |
确保在正确的文件系统级别委托用户权限。例如,用户 marks 被委托对本地和后代文件系统的 create、destroy 和 mount 权限。用户 marks 被委托对 tank 文件系统创建快照的本地权限,但不允许该用户对其自己的文件系统创建快照。因此,未在正确的文件系统级别对他委托 snapshot 权限。
# zfs allow -l marks snapshot tank # zfs allow tank ------------------------------------------------------------- Local permissions on (tank) user marks snapshot Local+Descendent permissions on (tank) user marks create,destroy,mount ------------------------------------------------------------- # su marks marks$ zfs snapshot tank/@snap1 marks$ zfs snapshot tank/marks@snap1 cannot create snapshot 'mark/marks@snap1': permission denied |
要在后代文件系统级别向用户 marks 委托权限,请使用 zfs allow -d 选项。例如:
# zfs unallow -l marks snapshot tank # zfs allow -d marks snapshot tank # zfs allow tank ------------------------------------------------------------- Descendent permissions on (tank) user marks snapshot Local+Descendent permissions on (tank) user marks create,destroy,mount ------------------------------------------------------------- # su marks $ zfs snapshot tank@snap2 cannot create snapshot 'tank@snap2': permission denied $ zfs snapshot tank/marks@snappy |
现在,用户 marks 只能在 tank 文件系统级别之下创建快照。
可向用户或组委托特定权限。例如,以下 zfs allow 命令将向 staff 组委托特定权限。此外,还会在创建 tank 文件系统后委托 destroy 和 snapshot 权限。
# zfs allow staff create,mount tank # zfs allow -c destroy,snapshot tank # zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) destroy,snapshot Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- |
由于用户 marks 是 staff 组的成员,因此他可以在 tank 中创建文件系统。此外,用户 marks 可以创建 tank/marks2 的快照,因为他具有执行此操作的特定权限。例如:
# su marks $ zfs create tank/marks2 $ zfs allow tank/marks2 ------------------------------------------------------------- Local permissions on (tank/marks2) user marks destroy,snapshot ------------------------------------------------------------- Create time permissions on (tank) destroy,snapshot Local+Descendent permissions on (tank) group staff create everyone mount ------------------------------------------------------------- |
但是,用户 marks 不能在 tank/marks 中创建快照,因为他不具有执行此操作的特定权限。例如:
$ zfs snapshot tank/marks2@snap1 $ zfs snapshot tank/marks@snappp cannot create snapshot 'tank/marks@snappp': permission denied |
在此示例中,用户 marks 在其起始目录中具有 create 权限,这意味着他可以创建快照。当文件系统通过 NFS 挂载时,此方案很有用。
$ cd /tank/marks2 $ ls $ cd .zfs $ ls snapshot $ cd snapshot $ ls -l total 3 drwxr-xr-x 2 marks staff 2 Dec 15 13:53 snap1 $ pwd /tank/marks2/.zfs/snapshot $ mkdir snap2 $ zfs list NAME USED AVAIL REFER MOUNTPOINT tank 264K 33.2G 33.5K /tank tank/marks 24.5K 33.2G 24.5K /tank/marks tank/marks2 46K 33.2G 24.5K /tank/marks2 tank/marks2@snap1 21.5K - 24.5K - tank/marks2@snap2 0 - 24.5K - $ ls snap1 snap2 $ rmdir snap2 $ ls snap1 |
以下示例说明如何创建权限集 @myset 并向组 staff 委托对 tank 文件系统的该权限集和 rename 权限。用户 cindys 是 staff 组成员,他具有在 tank 中创建文件系统的权限。但是,用户 lp 没有在 tank 中创建文件系统的权限。
# zfs allow -s @myset create,destroy,mount,snapshot,promote,clone,readonly tank # zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot ------------------------------------------------------------- # zfs allow staff @myset,rename tank # zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Local+Descendent permissions on (tank) group staff @myset,rename # chmod A+group:staff:add_subdirectory:fd:allow tank # su cindys cindys% zfs create tank/data Cindys% zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Local+Descendent permissions on (tank) group staff @myset,rename ------------------------------------------------------------- cindys% ls -l /tank total 15 drwxr-xr-x 2 cindys staff 2 Aug 8 14:10 data cindys% exit # su lp $ zfs create tank/lp cannot create 'tank/lp': permission denied |
# zfs allow dataset |
此命令显示针对指定数据集设置或允许的权限。输出包含以下组成部分:
权限集
各个权限或创建时权限
本地数据集
本地和后代数据集
仅后代数据集
以下输出表示用户 cindys 具有在 tank/cindys 文件系统上的 create、destroy、mount 和 snapshot 权限。
# zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot |
此示例中的输出指示针对 pool/fred 和 pool 文件系统的以下权限。
对于 pool/fred 文件系统:
定义了两个权限集:
@eng(create、destroy、snapshot、mount、clone、promote 和 rename)
@simple(create 和 mount)
为 @eng 权限集和 mountpoint 属性设置了创建时权限。创建时表示创建数据集后,便委托了 @eng 权限集和设置 mountpoint 属性的权限。
用户 tom 被委托对本地文件系统的 @eng 权限集,用户 joe 被委托对本地文件系统的 create、destroy 和 mount 权限。
用户 fred 被委托对本地和后代文件系统的 @basic 权限集,以及 share 和 rename 权限。
用户 barney 和 staff 组仅被委托对后代文件系统的 @basic 权限集。
对于 pool 文件系统:
定义了权限集 @simple(创建、销毁、挂载)。
组 staff 被授予对本地文件系统的 @simple 权限集。
下面是此示例的输出:
$ zfs allow pool/fred ------------------------------------------------------------------------------ Permission sets on (pool/fred) @eng create,destroy,snapshot,mount,clone,promote,rename @simple create,mount Create time permissions on (pool/fred) @eng,mountpoint Local permissions on (pool/fred) user tom @eng user joe create,destroy,mount Local+Descendent permissions on (pool/fred) user fred @basic,share,rename Descendent permissions on (pool/fred) user barney @basic group staff @basic ------------------------------------------------------------------------------ Permission sets on (pool) @simple create,destroy,mount Local permissions on (pool) group staff @simple ------------------------------------------------------------------------------ |
可以使用 zfs unallow 命令删除已委托的权限。例如,用户 cindys 具有在 tank/cindys 文件系统上的 create、destroy、mount 和 snapshot 权限。
# zfs allow cindys create,destroy,mount,snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot ------------------------------------------------------------- |
以下 zfs unallow 语法将从 tank/cindys 文件系统中删除用户 cindys 的快照权限:
# zfs unallow cindys snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount ------------------------------------------------------------- cindys% zfs create tank/cindys/data cindys% zfs snapshot tank/cindys@today cannot create snapshot 'tank/cindys@today': permission denied |
作为另一个示例,用户 marks 具有 tank/marks 文件系统上的以下权限:
# zfs allow tank/marks ------------------------------------------------------------- Local+Descendent permissions on (tank/marks) user marks create,destroy,mount ------------------------------------------------------------- |
以下 zfs unallow 语法将从 tank/marks 文件系统中删除用户 marks 的所有权限:
# zfs unallow marks tank/marks |
以下 zfs unallow 语法将删除对 tank 文件系统的权限集。
# zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Create time permissions on (tank) create,destroy,mount Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- # zfs unallow -s @myset tank $ zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) create,destroy,mount Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- |