JuiceFS v1.2-beta 1: ACL 功能全解析,更精细的权限控制

2024-04-26
黄杰烽

在最新的 JuiceFS v1.2-beta1 版本中,我们引入了对 POSIX ACL(POSIX Access Control Lists,以下简称 ACL)的支持。通过这个功能,用户能实现更细粒度的权限控制。

从早期的 UNIX-like 系统至今,最常使用的 permission mode 是"普通权限位" (OWNER, GROUP, OTHERS); 对于一些特殊场景, 还可以通过"特殊权限位" (SUID, SGID, STICKY) 附加"额外权限"。引入 ACL 后,用户可以进行更自由的策略组合,实现普通权限位无法完成的授权。

01 定义

ACL 遵循 POSIX 1003.2c draft 17 标准,但是在不同的系统中有细微差异,我们选择以 Linux 系统的实现为标准。

ACL 有两种分类:

  • Access ACL: 用于权限定义和检查,下文以及默认语义下的 ACL 所指;
  • Default ACL:结构与 Access ACL 相同,但仅应用于目录。子文件/子目录的 Access ACL将继承自父目录的 Default ACL。

下面介绍 ACL 的具体结构, 如下图所示,ACL 中每一项配置(即每一行)可以被称为一个条目(entry)。

分组 entry项 文本格式
owner class Owner user::rwx
group class Named user user:name:rwx
group class Owning group group::rwx
group class Named group group:name:rwx
group class Mask mask::rwx
other class Others other::rwx

ACL 相比普通 perm mode 增加了三项,已在上图中用蓝色标出:named user, named group 以及 mask。

  • named user 可以指定多用户的权限, 拓展了原来只有 owner 的权限;
  • named group 与 named user 类似, 拓展了用户组的权限;
  • mask 比较特殊, 后文会继续做详细介绍。mask 与 umask 不同,并且设置了 ACL 的情况下, umask 会被忽略。

ACL 与 perm mode 是完全兼容的。从定义上我们可以做以下分类:

  • Minimal/Miminum ACL: 等同于普通 perm mode;
  • Extended ACL: 配置了任意 named user 或 named group 项。

下面操作展示了 ACL 与 perm mode 之间的关联性。

# 查看permission mode
$ ls -l
drwxr-xr-x 2 root root 4.0K  4月 12 09:32 d1

# 通过setfacl设置d1目录的group1组权限
$ setfacl -m g:group1:rwx d1

# 再次查看permission mode
$ ls -l
drwxrwxr-x+ 2 root root 4.0K  4月 12 09:32 d1

设置了 ACL 之后,文件 perm mode 的 group class 也发生了变化, 增加了“w”权限。这是因为 ACL 拓展了 group class(请参考表格1中的分组)。

perm mode 中的 group class 仅代表了 owner group 的权限,但 ACL 中代表 group class 所有条目的权限上界。因此 group class 的权限位也会随条目变动而变化.

上文提到 ACL 中新增的条目“mask”,该条目用于表示 group class 的动态权限变化。设置了 ACL ,perm mode 的 group class 显示就是 mask。

权限 mode 和 ACL 的映射关系
权限 mode 和 ACL 的映射关系

默认通过 setfacl 设置 ACL, 会自动计算出 mask。比如上文所示, mask = owner group entry | group1 entry, 取并集"rwx"; 也可以独立设置 mask, 则 group class 中 entry 项的最终权限需要与 mask 取交集. 如下文:

  • owner group 最终生效的权限为: "r-x" & "-wx" = "--x"
  • group1 权限为: "rwx" & "-wx" = "-wx"
# 接上文操作, 设置mask为"-wx"
$ setfacl -m m::-wx d1

# 查看ACL
$ getfacl d1 --omit-header
user::rwx
group::r-x                      #effective:--x
group:group1:rwx                #effective:-wx
mask::-wx
other::r-x

02 实现

ACL 提供了更精细的权限管理功能,但也增加了一定的性能损耗。因此,本章节将详细解释 JuiceFS 在存储空间和性能方面实施的优化策略。

ACL 复用

ACL 与文件直接关联,可以视为文件的一个扩展属性。在一些文件系统实现中,每个文件都会在扩展属性(xattr)中单独保存一份 ACL,这会增加大量的元数据。

JuiceFS ACL 的存储结构定义如下, 假如文件系统中以万计的文件都保存一份相应配置, 新增存储需求太过庞大且低效。

type ACL struct {
    Owner       uint16
    Group       uint16
    Mask        uint16
    Other       uint16
    NamedUsers  []Entry
    NamedGroups []Entry
}

type Entry struct {
    Id   uint32 // 用户Id or 组Id
    Perm uint16
}

常见的使用场景中, ACL 的配置并不会太多; 并且使用 Default ACL 的目录, 其下创建的文件对象都继承相同的Access ACL。

因此 JuiceFS 实现中做了 ACL 复用优化。具体而言,我们将 ACL 与 xattr 解耦,存储在独立的元数据引擎结构中, 并将相同的 ACL 映射到一个全局唯一的配置上,显著减少重复数据的存储需求。在文件对象中,只需储存一个 ACL ID。这个 ACL ID 是由元数据引擎分配的,确保全局唯一且递增,有效避免了多客户端(如多个挂载点)之间的冲突。结合本地缓存的使用,文件的 ACL 权限检查的性能损耗可降至与常规权限模式相近的水平;此外,这种方法还提高了在 Default ACL 场景下文件对象创建的性能,因为只需为文件对象分配一个 ACL ID,从而减少了元数据引擎处理存储 ACL 请求的频率。

ACL Cache

开启 ACL 后, 每一次文件对象操作, 内核 (kernel) 需要先获取 ACL, 然后执行 ACL 权限检查。因此,高效获取 ACL 至关重要。如果每次请求需要从元数据引擎中读取 ACL 配置, 将增加性能损耗。基于 ACL 复用的前提, JuiceFS 在客户端中缓存了所有 ACL 配置. 并且文件对象属性中保存有 ACL ID, 读取 ACL 只需要简单的一次内存索引操作。

目前实现中, ACL 只新增不变更, 所以不同客户端的 ACL 缓存只需同步新增的 ACL 配置。若缓存读取失败会从元数据引擎加载缺失的 ACL 配置。由于 ACL 配置新增是一个低频操作, 因此这部分性能损耗也是可控的。

Minimal ACL

对于文件系统中以万计的文件对象, 我们可能仅需要对极少数的文件做更严格的 ACL 管理. 其他的文件相当于拥有 Minimal ACL, 管理与原权限 mode 一致。

因此 JuiceFS 实现中, 在逻辑上做了兼容, 对于 Minimal ACL, 并不会实际创建和存储 ACL, 性能与开启 ACL 功能前基本一致。

03 性能

开启 ACL 功能必然增加一些性能负担,因此我们对开启 ACL 功能前后的性能做了压测对比, 性能损耗在 5% 左右, 具体数据如下:

  • 机器配置:4c, 16g
  • 元数据引擎: Redis
  • 数据集:100w文件,每个文件夹文件数100
  • ACL配置:400 user 和 default user, 200 group 和 default group
operation acl(op/s) no-acl(op/s)
create 7436 7965
mkdir 6976 7451
open 1219 1173
rename 409 424
ls 1442 1490
delete 968 919
chmod 1219 1220
hardlink 740 765
symlink 8972 8877
setxattr 1208 1298

04 使用

在 JuiceFS中, 可参考 POSIX ACL 文档开启 ACL 功能, 然后通过 setfacl/getfacl 工具设置和查看 ACL 配置。

ACL 的权限检查与 perm mode 类似, 逐条目匹配. 具体规则不再赘述, 可参考文档

👏 欢迎大家下载试用,我们也期待你提供宝贵的反馈和意见:https://github.com/juicedata/juicefs/releases/tag/v1.2.0-beta1

Author

黄杰烽
Juicedata 系统工程师

相关博客

JuiceFS v1.2-beta1,Gateway 升级,多用户场景权限管理更灵活

2024-04-22
JuiceFS v1.2-beta1 今天正式发布。在这个版本中,除了进行了大量使用体验优化和 bug 修复外,新增三个特性:Gateway 功能扩展、支持 POSIX ACL、支持平滑升级。