概述
Hadoop分布式文件系统(HDFS)的权限模型与POSIX模型的文件和目录权限模型一致。每个文件和目录与所有者和组相关联。该文件或目录将权限划分为所有者的权限,作为该组成员的其他用户的权限、以及所有其他用户的权限。对于文件,需要r权限才能读取文件,并且需要w权限才能写入或附加到文件中。对于目录,需要r权限来列出目录的内容,创建或删除文件或目录所需的w权限,并且需要x权限来访问目录的子目录。
与POSIX模型相反,文件没有setuid或setgid位,因为没有可执行文件的概念。对于目录,没有setuid或setgid位目录作为简化。粘贴位可以在目录上设置,防止除超级用户,目录所有者或文件所有者以外的任何人删除或移动目录中的文件。设置文件的粘贴位没有任何效果。总的来说,文件或目录的权限是它的模式。一般来说,将使用用于表示和显示模式的Unix海关,包括在本说明书中使用八进制数字。创建文件或目录时,其所有者是客户端进程的用户标识,其组是父目录(BSD规则)的组。
HDFS还为POSIX ACL(访问控制列表)提供可选支持,以通过针对特定命名用户或命名组的更细粒度的规则来增加文件权限。ACL将在本文档后面更详细的讨论。
访问HDFS的每个客户端进程都具有由用户名和组列表组成的两部分身份。每当客户端进程访问HDFS文件或目录foo都会进行权限检查:
- 如果用户名匹配foo的所有者,则验证所有者权限;
- 否则,如果foo的组与组列表中的任何成员相匹配,则验证组权限;
- 否则,验证foo的其他权限。
如果权限检查失败,则客户机操作失败。
用户身份
从Hadoop 0.22开始,Hadoop支持两种不同的操作模式来确定用户的身份,由hadoop.security.authentication属性指定:
simple
在这种操作模式下,客户端进程的身份由主机操作系统决定。在类Unix系统上,用户名等同于`whoami`。
kerberos
在Kerberos操作中,客户端进程的身份由其Kerberos凭据确定。例如,在Kerberos环境中,用户可以使用kinit实用程序来获取Kerberos票证授权(TGT),并使用klist来确定其当前的主体。将Kerberos principal映射到HDFS用户名时,只认证域名(realm)之前的用户信息。例如,一个principal todd/foobar@CORP.COMPANY.COM将作为HDFS上的简单用户名todd。
不管操作模式如何,用户身份机制对于HDFS本身是外在的。HDFS中没有规定创建用户身份,建立组或处理用户凭据。
组映射
一旦用户名被确定如上所述,组列表由组映射服务确定,由hadoop.security.group.mapping属性配置。有关详细信息,请参阅Hadoop组映射。
权限检查
每个HDFS操作要求用户具有通过文件所有权,组成员身份或其他权限授予的特定权限(READ,WRITE和EXECUTE的某些组合)。操作可以在路径的多个组件执行权限检查,而不仅仅是最终的组件。此外,一些操作取决于对路径所有者的检查。
所有操作都需要遍历访问。遍历访问需要对路径的所有现有组件执行EXECUTE权限,但最终路径组件除外。例如,对于任何访问/ foo/bar/baz的操作,调用者必须在/,/ foo和/ foo / bar上具有EXECUTE权限。
下表描述了HDFS为路径的每个组件执行的权限检查。
所有权:是否检查呼叫者是否是路径的所有者。通常,更改所有权或权限元数据的操作要求呼叫者是所有者。
Parent:所请求路径的父目录。例如,对于路径/ foo / bar / baz,父级是/ foo / bar。
祖先:所请求路径的最后一个现有组件。例如,对于路径/ foo / bar / baz,如果/ foo / bar存在,则祖先路径为/ foo / bar。如果/ foo存在但是/ foo / bar不存在,则祖先路径为/ foo。
最终:请求的路径的最终组件。例如,对于路径/ foo / bar / baz,最终的路径组件是/ foo / bar / baz。
子树:对于作为目录的路径,目录本身及其所有子子目录,递归。例如,对于路径/ foo / bar / baz,它有两个名为buz和boo的子目录,子树是/ foo / bar / baz,/ foo / bar / baz / buz和/ foo / bar /巴兹/嘘声。
Operation | Ownership | Parent | Ancestor | Final | Sub-tree |
append | NO | N/A | N/A | WRITE | N/A |
concat | NO [2] | WRITE (sources) | N/A | READ (sources), WRITE (destination) | N/A |
create | NO | N/A | WRITE | WRITE [1] | N/A |
createSnapshot | YES | N/A | N/A | N/A | N/A |
delete | NO [2] | WRITE | N/A | N/A | READ, WRITE, EXECUTE |
deleteSnapshot | YES | N/A | N/A | N/A | N/A |
getAclStatus | NO | N/A | N/A | N/A | N/A |
getBlockLocations | NO | N/A | N/A | READ | N/A |
getContentSummary | NO | N/A | N/A | N/A | READ, EXECUTE |
getFileInfo | NO | N/A | N/A | N/A | N/A |
getFileLinkInfo | NO | N/A | N/A | N/A | N/A |
getLinkTarget | NO | N/A | N/A | N/A | N/A |
getListing | NO | N/A | N/A | READ, EXECUTE | N/A |
getSnapshotDiffReport | NO | N/A | N/A | READ | READ |
getStoragePolicy | NO | N/A | N/A | READ | N/A |
getXAttrs | NO | N/A | N/A | READ | N/A |
listXAttrs | NO | EXECUTE | N/A | N/A | N/A |
mkdirs | NO | N/A | WRITE | N/A | N/A |
modifyAclEntries | YES | N/A | N/A | N/A | N/A |
removeAcl | YES | N/A | N/A | N/A | N/A |
removeAclEntries | YES | N/A | N/A | N/A | N/A |
removeDefaultAcl | YES | N/A | N/A | N/A | N/A |
removeXAttr | NO [2] | N/A | N/A | WRITE | N/A |
rename | NO [2] | WRITE (source) | WRITE (destination) | N/A | N/A |
renameSnapshot | YES | N/A | N/A | N/A | N/A |
setAcl | YES | N/A | N/A | N/A | N/A |
setOwner | YES [3] | N/A | N/A | N/A | N/A |
setPermission | YES | N/A | N/A | N/A | N/A |
setReplication | NO | N/A | N/A | WRITE | N/A |
setStoragePolicy | NO | N/A | N/A | WRITE | N/A |
setTimes | NO | N/A | N/A | WRITE | N/A |
setXAttr | NO [2] | N/A | N/A | WRITE | N/A |
truncate | NO | N/A | N/A | WRITE | N/A |
[1]使用者使用overrite选项调用create操作时,并且路径上存在现有文件时,将会验证最终路径上的WRITE访问权限。
[2]任何检查父目录上的写入权限的操作也会检查所有权是否设置了粘滞位。
[3]调用setOwner来更改拥有文件的用户需要HDFS超级用户访问。HDFS超级用户访问不需要更改组,但调用者必须是文件的所有者和指定组的成员。
实现原理
每个文件或目录操作将完整路径名称传递给NameNode,并且每个操作的路径都应用权限检查。客户端框架将隐式地将用户ID与与NameNode连接的UNIX用户相关联,从而减少对现有客户机API的更改的需要。一般情况下,当文件中的一个操作成功时,另一个操作会因为文件或路径上的某些目录不再存在,而操作失败。例如,当客户端首次开始读取文件时,它首先向NameNode发出请求以发现文件的第一个块的位置,其他请求要求读取其他块可能会失败。另一方面,删除文件不会撤销已知道文件块的客户端的访问权限。通过添加权限,可以在请求之间撤销客户端对文件的访问。再次,更改权限不会撤销已知道文件块的客户端的访问。
File System API的变更
如果权限检查失败,则使用路径参数的所有方法将抛出AccessControlException。
新方法:
- public FSDataOutputStream create(Path f, FsPermission permission, boolean overwrite, int bufferSize, short replication, long blockSize, Progressable progress) throws IOException;
- public boolean mkdirs(Path f, FsPermission permission) throws IOException;
- public void setPermission(Path p, FsPermission permission) throws IOException;
- public void setOwner(Path p, String username, String groupname) throws IOException;
- public FileStatus getFileStatus(Path f) throws IOException;will additionally return the user, group and mode associated with the path.
新的文件或目录的模式被umask set限制为配置参数。当使用现有的create(path,...)方法(没有权限参数)时,新文件的模式为0666。当使用新的create(path,permission,...)方法(具有权限参数P)时,新文件的模式为 P & ^umask & 0666。当使用现有的mkdirs(路径)方法(没有权限参数)创建新目录时,新目录的模式为0777。当使用新的mkdirs(路径,权限)方法(具有权限参数P)时,新目录的模式为P & ^umask & 0777.
Application Shell的变更
新操作:
- chmod [-R] mode file ...
Only the owner of a file or the super-user is permitted to change the mode of a file. - chgrp [-R] group file ...
The user invoking chgrp must belong to the specified group and be the owner of the file, or be the super-user. - chown [-R] [owner][:[group]] file ...
The owner of a file may only be altered by a super-user. - ls file ...
- lsr file ...
The output is reformatted to display the owner, group and mode.
超级用户
超级用户是与NameNode进程本身具有相同标识的用户。简单来说,如果你启动了NameNode,那么你是超级用户。超级用户可以做任何事情,超级用户的权限检查永远不会失败。谁是超级用户谁不是永恒的观念?当NameNode启动时,进程标识确定当前是超级用户。HDFS超级用户不必是NameNode主机的超级用户,也不需要所有集群都具有相同的超级用户。此外,在个人工作站上运行HDFS的实验人员,无需任何配置即可成为该安装的超级用户。
此外,管理员可以使用配置参数标识一个区别的组。如果设置,该组的成员也是超级用户。
WEB SERVER
默认情况下,Web服务器的身份是配置参数。也就是说,NameNode没有真实用户的身份的概念,但是Web服务器的行为就好像它具有由管理员选择的用户的身份(用户和组)一样。除非所选的身份与超级用户相匹配,否则名称空间的某些部分可能无法访问Web服务器。
ACLs
除了传统的POSIX权限模型,HDFS还支持POSIX ACL(访问控制列表)。ACL对于实现与用户和组的自然组织层次结构不同的权限要求很有用。ACL提供了一种为特定命名用户或命名组设置不同权限的方法,不仅是文件的所有者和文件的组。
缺省情况下,禁止对ACL的支持,NameNode不允许创建ACL。要启用对ACL的支持,请在NameNode配置中将dfs.namenode.acls.enabled设置为true。
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。
此外,还有两个扩展的ACL条目用于指定的用户bruce和指定组的sales,两者都被授予完全访问权限。掩码是一个特殊的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
配置参数
dfs.permissions = true
true,则打开前文所述的权限系统。如果是 false,权限检查 就是关闭的,但是其他的行为没有改变。这个配置参数的改变并不改变文件或目录的模式、所有者和组等信息。
不管权限模式是开还是关,chmod,chgrp 和 chown 总是 会检查权限。这些命令只有在权限检查背景下才有用,所以不会有兼容性问题。这样,这就能让管理员在打开常规的权限检查之前可以可靠地设置文件的所有者和权限。
dfs.web.ugi = webuser,webgroup
Web服务器使用的用户名。如果将这个参数设置为超级用户的名称,则所有Web客户就可以看到所有的信息。如果将这个参数设置为一个不使用的用户,则Web客户就只能访问到“other”权限可访问的资源了。额外的组可以加在后面,形成一个用逗号分隔的列表。
dfs.permissions.supergroup = supergroup
超级用户的组名。
dfs.upgrade.permission = 777
升级时的初始模式。文件
永不会被设置
x权限。在配置文件中,可以使用十进制数
51110。
dfs.umask = 022
umask参数在创建文件和目录时使用。在配置文件中,可以使用十进制数1810。