> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/di-24-zhang-zfs-wen-jian-xi-tong/di-24.7-jie-zfs-wei-tuo-guan-li.md).

# 24.7 ZFS 委托管理

ZFS 提供全面的权限委托系统，允许非特权用户执行 ZFS 管理操作。

例如，如果每个用户的主目录是一个数据集，用户需要获得创建和销毁其主目录快照的权限。执行备份的用户可以获得使用复制功能的权限。

ZFS 还允许使用统计脚本，仅访问所有用户的空间使用数据。权限的委托能力本身也可委托。权限委托适用于每个子命令和大多数属性。

## 用户级 ZFS 管理

ZFS 委托管理（ZFS delegation）提供细粒度的权限控制，让系统管理员将特定的 ZFS 管理权限授予非特权用户。自 FreeBSD 14.1 起，adduser 会自动为非特权用户的 ZFS 主目录创建独立数据集并支持加密。

该变更（commit 516009ce8d38）使 adduser(8) 在用户主目录的父目录为 ZFS 数据集时，自动为用户创建独立 ZFS 数据集，例如 **/home/xxx** 继承自 **/home**。`adduser` 的 `-Z` 参数可禁用此行为，同时支持为非特权用户的 ZFS 主目录启用加密。

## 基础用户级 ZFS 管理

以非特权用户的 ZFS 数据集为例。安装系统时手动创建了两个普通用户 aria2 和 safreya。

列出系统中所有 ZFS 文件系统及其属性：

```sh
% 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
```

其中：

```sh
zroot/home/aria2                               128K   396G   128K  /home/aria2
zroot/home/safreya                            7.74G   396G  7.70G  /home/safreya
```

即在创建用户时，系统已默认为用户 aria2 和 safreya 分别创建了各自独立的数据集 zroot/home/aria2 和 zroot/home/safreya。

接下来，分别查看两个数据集上的用户权限。

```sh
% zfs allow zroot/home/aria2        # 显示或设置 zroot/home/aria2 文件系统的权限授权
---- Permissions on zroot/home/aria2 ---------------------------------
Local+Descendent permissions:
        user aria2 create,destroy,mount,snapshot
safreya ~ % zfs allow zroot/home/safreya
---- Permissions on zroot/home/safreya -------------------------------
Local+Descendent permissions:
        user safreya create,destroy,mount,snapshot
```

由输出可知，系统在创建用户时，会默认为其数据集授予 create、destroy、mount 和 snapshot 四项权限。

ZFS 委托权限存储在数据集的元数据中。`Local+Descendent permissions` 表示该权限设置既适用于当前数据集，其作用范围也覆盖其子数据集。

`zfs allow <用户> allow <数据集>` 赋予指定用户在目标数据集或其子数据集上将他们所拥有的任何权限委派给其他用户的能力。如果某用户拥有 snapshot 权限与 allow 权限，该用户可以将 snapshot 权限授予其他用户。

因此，对于这两个数据集，普通用户也可使用快照功能：

```sh
% zfs snapshot zroot/home/safreya@snap1   # 为 zroot/home/safreya 文件系统创建快照 snap1
% zfs list -t snap                        # 列出所有 ZFS 快照
NAME                                       USED  AVAIL  REFER  MOUNTPOINT
zroot/home/safreya@snap1                     0B      -  7.70G  -
```

再来看 `create`、`destroy` 和 `mount` 权限：

```sh
% zfs create zroot/home/safreya/dataset_1        # 在 zroot/home/safreya 下创建一个新的 ZFS 数据集 dataset_1
cannot mount 'zroot/home/safreya/dataset_1': Insufficient privileges
filesystem successfully created, but not mounted
```

创建新数据集涉及挂载，这要求将 FreeBSD 的 `sysctl vfs.usermount` 设置为 1，以允许非 root 用户挂载文件系统。

```sh
% su -m root -c 'sysctl vfs.usermount=1'
Password:
vfs.usermount: 0 -> 1
% zfs create zroot/home/safreya/dataset_2        # 在 zroot/home/safreya 下创建一个新的 ZFS 数据集 dataset_2
% zfs list        # 列出所有 ZFS 文件系统及其属性
NAME                                           USED  AVAIL  REFER  MOUNTPOINT

      ...此处省略一部分...

zroot/home                                    7.79G   396G    96K  /home
zroot/home/aria2                               128K   396G   128K  /home/aria2
zroot/home/safreya                            7.79G   396G  7.68G  /home/safreya
zroot/home/safreya/dataset_1                    96K   396G    96K  /home/safreya/dataset_1
zroot/home/safreya/dataset_2                    96K   396G    96K  /home/safreya/dataset_2

      ...此处省略一部分...
```

```sh
% zfs destroy zroot/home/safreya/dataset_1       # 删除 ZFS 数据集 zroot/home/safreya/dataset_1
% zfs destroy zroot/home/safreya/dataset_2        # 删除 ZFS 数据集 zroot/home/safreya/dataset_2
```

由输出可知，创建和销毁权限可正常运行。为了防止滥用，还有另一个限制：非 root 用户必须拥有挂载点的所有权，才能挂载文件系统。

至此，用户级 ZFS 管理的基本功能已就绪。但 `rollback` 权限默认不可用，需由 root 用户为普通用户单独授予。

将 zroot/home/safreya 文件系统回滚到 snap1 快照状态：

```sh
% zfs rollback zroot/home/safreya@snap1
cannot rollback 'zroot/home/safreya': permission denied
```

以 root 用户授予 `safreya` 用户对 `zroot/home/safreya` 文件系统执行回滚操作的权限：

```sh
% su -m root -c 'zfs allow safreya rollback zroot/home/safreya'
Password:
% zfs rollback zroot/home/safreya@snap1
```

## 用户级 ZFS 加密功能

在 FreeBSD 14.1 中，如果要在用户级使用 ZFS 加密功能，必须为用户授予特定权限。

授权用户 safreya 对 zroot/home/safreya 文件系统执行密钥管理和加密操作：

```sh
% su -m root -c 'zfs allow safreya change-key,load-key,keyformat,keylocation,encryption zroot/home/safreya'
Password: # 此处输入 root 账户密码随后按回车键
```

显示 `zroot/home/safreya` 文件系统的当前权限授权设置：

```sh
% zfs allow zroot/home/safreya
---- Permissions on zroot/home/safreya -------------------------------
Local+Descendent permissions:
        user safreya change-key,create,destroy,encryption,keyformat,keylocation,load-key,mount,snapshot
```

`change-key`、`load-key`、`keyformat`、`keylocation` 和 `encryption` 这五项权限属性用于 ZFS 的加密功能。

创建启用加密的 ZFS 数据集 `zroot/home/safreya/secret`，并将密码用作密钥格式：

```sh
% zfs create -o encryption=on -o keyformat=passphrase zroot/home/safreya/secret
Enter new passphrase:     # 在此处输入密码，密码不会回显
Re-enter new passphrase:  # 在此处重复输入密码，密码不会回显
```

查看加密情况：

```sh
% zfs get mounted zroot/home/safreya/secret        # 查询 zroot/home/safreya/secret 数据集是否已挂载
NAME                       PROPERTY  VALUE    SOURCE
zroot/home/safreya/secret  mounted   yes      -
```

查看 `mounted` 属性，加密数据集创建即挂载，现在创建一份文件，随后卸载加密数据集：

```sh
% cd secret                                      # 进入 secret 数据集目录
% echo "a secret makes a man mad" > abc.txt     # 在 secret 数据集中创建文件 abc.txt 并写入内容
% cd ..                                          # 返回上一级目录
% zfs unmount zroot/home/safreya/secret         # 卸载 secret 数据集
% zfs unload-key zroot/home/safreya/secret      # 卸载 secret 数据集的加密密钥
% zfs get mounted zroot/home/safreya/secret     # 查询 secret 数据集是否已挂载
NAME                       PROPERTY  VALUE    SOURCE
zroot/home/safreya/secret  mounted   no       -
% ls secret # 并无输出

```

卸载加密数据集时必须同时卸载其密钥，挂载数据集时也必须先加载密钥：

```sh
% zfs load-key zroot/home/safreya/secret   # 加载 secret 数据集的加密密钥
Enter passphrase for 'zroot/home/safreya/secret':  # 提示输入密钥密码
% zfs mount zroot/home/safreya/secret      # 挂载 secret 数据集
% ls secret                                 # 列出 secret 数据集中的文件
Permissions Size User    Date Modified Name
.rw-r--r--    25 safreya 19 Sep 20:26  abc.txt
```

> **警告**
>
> 因为 `destroy` 权限默认已授予用户，所以无论数据集是否挂载，`destroy` 子命令都可以成功销毁数据集。因此如果操作者不是该用户本人，仍可能删除数据集。
>
> 授权即授予普通用户代理权限，使其在操作授权的数据集时拥有类似 root 的权限，无需输入密码。因此，在授予权限时应合理限制授权范围和权限属性，例如禁用 `destroy` 权限属性等。

撤销用户 safreya 对 zroot/home/safreya 文件系统的销毁权限：

```sh
% su -m root -c 'zfs unallow safreya destroy zroot/home/safreya'
Password:        # 此处输入 root 账户密码随后按回车键
```

显示 `zroot/home/safreya` 文件系统的当前权限授权设置：

```sh
% zfs allow zroot/home/safreya
---- Permissions on zroot/home/safreya -------------------------------
Local+Descendent permissions:
        user safreya change-key,create,encryption,keyformat,keylocation,load-key,mount,rollback,snapshot
```

此处，**zroot/home/safreya/secret** 受 **zroot/home/safreya** 上 `Local+Descendent` 权限的作用范围覆盖。ZFS 委托权限不存在继承机制，权限存储在授予它的数据集上，`Local+Descendent` 表示该权限的作用范围同时覆盖本数据集及其子孙数据集。在父数据集上撤销权限时，其 Descendent 范围也会移除，子孙数据集上的用户将失去相应权限。如果需要对子孙数据集单独控制权限，需要显式地在子孙数据集上授权或撤销。

## adduser 与用户主目录加密

adduser 命令可直接使用加密的用户主目录数据集，但默认授予的权限不足，卸载后普通用户无法直接挂载。

```sh
# adduser        # 在系统中添加新用户，按照提示输入用户名、密码及其他信息
Username: test

……省略无关内容……

Enable ZFS encryption? (yes/no) [no]: yes #该功能为新增功能

……省略无关内容……
ZFS dataset : zroot/home/test

Enter encryption keyphrase for ZFS dataset (zroot/home/test):
Enter new passphrase:
Re-enter new passphrase:
adduser: INFO: Successfully created ZFS dataset (zroot/home/test).
adduser: INFO: Successfully added (test) to the user database.
```

查看 `zroot/home/test` 文件系统的当前权限授权设置：

```sh
# zfs allow zroot/home/test
---- Permissions on zroot/home/test ----------------------------------
Local+Descendent permissions:
        user test create,destroy,mount,snapshot
```

卸载数据集和密钥：

```sh
# zfs unmount zroot/home/test        # 卸载 zroot/home/test 数据集
# zfs unload-key zroot/home/test     # 卸载 zroot/home/test 数据集的加密密钥
```

切换到普通用户 `test` 尝试挂载：

```sh
# su test        # 切换到普通用户 test
$ zfs load-key zroot/home/test        # 加载 zroot/home/test 数据集的加密密钥
Enter passphrase for 'zroot/home/test':
Key load error: Permission denied.
```

`Permission denied` 表示权限不足，访问被拒绝。

## 参考文献

* OpenZFS Project. man zfs-allow\[EB/OL]. \[2026-04-02]. <https://openzfs.github.io/openzfs-docs/man/master/8/zfs-allow.8.html>. OpenZFS 官方 zfs-allow 命令手册。
* FreeBSD Project. zfs-allow -- delegate ZFS administration permissions to unprivileged users\[EB/OL]. \[2026-04-02]. <https://man.freebsd.org/cgi/man.cgi?query=zfs-allow&sektion=8>. FreeBSD 官方 zfs-allow 命令手册。
* FreeBSD Project. zfs-create -- create ZFS dataset\[EB/OL]. \[2026-04-02]. <https://man.freebsd.org/cgi/man.cgi?query=zfs-create&sektion=8>. FreeBSD 官方 zfs-create 命令手册。
* FreeBSD Project. FreeBSD Handbook, Chapter 22 The Z File System (ZFS)\[EB/OL]. \[2026-04-24]. <https://docs.freebsd.org/en/books/handbook/zfs/>. FreeBSD 手册中关于 ZFS 的章节。
* FreeBSD Foundation. OpenZFS Encryption Arrives on FreeBSD\[EB/OL]. (2020-07)\[2026-04-02]. <https://freebsdfoundation.org/wp-content/uploads/2020/07/OpenZFS-Encryption-Arrives-on-FreeBSD.pdf>. 说明 GELI 加密与 ZFS 加密的异同点。
* FreeBSD Project. Merge OpenZFS support in to HEAD\[EB/OL]. \[2026-04-02]. <https://cgit.freebsd.org/src/commit/?id=9e5787d2284e>. FreeBSD 13.0 转向 OpenZFS 的提交记录。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/di-24-zhang-zfs-wen-jian-xi-tong/di-24.7-jie-zfs-wei-tuo-guan-li.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
