2026-01-30 13:05:30Apache Hadoop 3.3.6

ACL(访问控制列表)

除了传统的 POSIX 权限模型外,HDFS 还支持 POSIX ACL(访问控制列表)。ACL 可用于实现与用户和组的自然组织层次结构不同的权限要求。ACL 提供了一种为特定的已命名用户或已命名组(不仅是文件的拥有者和文件的组)设置不同权限的方法。

默认情况下,支持 ACL,并且 NameNode 允许创建 ACL。要禁用对 ACL 的支持,请在 NameNode 配置中将 dfs.namenode.acls.enabled 设置为 false。

ACL 由一组 ACL 条目组成。每个 ACL 条目都指定一个特定用户或组,并为该特定用户或组授予或拒绝读取、写入和执行权限。例如

user::rw-

user:bruce:rwx #effective:r--

group::r-x #effective:r--

group:sales:rwx #effective:r--

mask::r--

other::r--

ACL 条目由类型、可选名称和权限字符串组成。出于显示目的,“:”用作每个字段之间的分隔符。在此示例 ACL 中,文件所有者具有读写访问权限,文件组具有读执行访问权限,其他人具有读取访问权限。到目前为止,这等效于将文件的权限位设置为 654。

此外,还有 2 个针对已命名用户 bruce 和已命名组 sales 的扩展 ACL 条目,两者都授予完全访问权限。掩码是一个特殊的 ACL 条目,它会筛选授予所有已命名用户条目和已命名组条目的权限,以及未命名组条目。在此示例中,掩码仅具有读取权限,我们可以看到,几个 ACL 条目的有效权限已相应地进行了筛选。

每个 ACL 都必须具有一个掩码。如果用户在设置 ACL 时未提供掩码,则会通过计算所有将被掩码过滤的项的权限的并集自动插入掩码。

对具有 ACL 的文件运行 chmod 实际上会更改掩码的权限。由于掩码充当过滤器,因此这会有效地限制所有扩展 ACL 项的权限,而不是仅更改组项,并且可能会遗漏其他扩展 ACL 项。

该模型还区分“访问 ACL”(定义在权限检查期间强制执行的规则)和“默认 ACL”(定义新子文件或子目录在创建期间自动接收的 ACL 项)。例如

user::rwx

group::r-x

other::r-x

default:user::rwx

default:user:bruce:rwx #effective:r-x

default:group::r-x

default:group:sales:rwx #effective:r-x

default:mask::r-x

default:other::r-x

只有目录可以具有默认 ACL。当创建新文件或子目录时,它会自动将父目录的默认 ACL 复制到其自己的访问 ACL 中。新的子目录也会将其复制到其自己的默认 ACL 中。通过这种方式,当创建新的子目录时,默认 ACL 将被复制到文件系统树的任意深层级。

新子项访问 ACL 中的确切权限值受模式参数的过滤影响。考虑到默认 umask 为 022,对于新目录通常为 755,对于新文件通常为 644。模式参数过滤了未命名用户(文件所有者)、掩码和其他用户的复制权限值。使用此特定示例 ACL,并使用模式为 755 创建新的子目录,此模式过滤对最终结果没有影响。但是,如果我们考虑创建模式为 644 的文件,则模式过滤会导致新文件的 ACL 对未命名用户(文件所有者)接收读写权限,对掩码接收读取权限,对其他用户接收读取权限。此掩码还意味着已命名用户 bruce 和已命名组 sales 的有效权限仅为读取。

请注意,复制发生在创建新文件或子目录时。对父项的默认 ACL 的后续更改不会更改现有子项。

默认 ACL 必须具有所有最低要求的 ACL 条目,包括未命名用户(文件所有者)、未命名组(文件组)和其他条目。如果用户在设置默认 ACL 时未提供其中一个条目,则会通过从访问 ACL 复制相应的权限或在没有访问 ACL 时复制权限位自动插入这些条目。默认 ACL 还必须具有掩码。如上所述,如果未指定掩码,则会通过计算掩码将过滤的所有条目上的权限的并集自动插入掩码。

请注意,对于给定的文件或目录,ACL 条目的数量不能无限。访问条目的最大数量为 32,默认条目的最大数量为 32,总共为 64。

在考虑具有 ACL 的文件时,权限检查算法将更改为

如果用户名与文件所有者匹配,则测试所有者权限;

否则,如果用户名与其中一个命名用户条目中的名称匹配,则测试这些权限,并通过掩码权限进行过滤;

否则,如果文件的组与组列表中的任何成员匹配,并且由掩码过滤的这些权限授予访问权限,则使用这些权限;

否则,如果命名组条目与组列表中的成员匹配,并且由掩码过滤的这些权限授予访问权限,则使用这些权限;

否则,如果文件组或任何命名组条目与组列表中的成员匹配,但这些权限未授予任何访问权限,则拒绝访问;

否则,测试文件的其他权限。

最佳做法是依靠传统的权限位来实现大多数权限要求,并定义较少数量的 ACL 以使用一些例外规则来扩充权限位。与仅具有权限位的文件相比,具有 ACL 的文件在 NameNode 中会产生额外的内存开销。