HDFS 权限管理

HDFS Permissions Guide

Overview

HDFS 实现了文件和目录的权限模型,很多跟POSIX模型共享。 每个文件、目录都关联到用户、组。文件、目录对于拥有者、组中的其他用户、其他用户有着不同的权限设置。对于文件,读取需要r权限,写入/追加需要w权限。对于目录,列出目录内容需要r权限,创建、删除文件或目录需要w权限,访问目录子项需要x权限。

与POSIX模型不同,因为没有可执行文件,所以文件没有setuid or setgid bits。对于目录,也没有setuid or setgid bits作为简化。粘滞位sticky bit可以被作用于目录,放置除superuser、目录所有者、文件所有者之外的任何用户删除、移动目录内的文件。粘滞位sticky bit对于文件不生效。 文件或目录的权限我们称为 mod。一般来说,mdoe的展示使用Unix风格,比如描述的8进制数使用。当创建一个文件/目录后,它的所有者即为客户端进程的用户,它的组是父目录的组(BSD规则)。

HDFS 还支持POSIX ACLs (Access Control Lists),给指定用户、组配置更新颗粒度的规则来加强权限管理。ACLs稍后会详细介绍。

每个访问HDFS的客户端进程身份都有两部分组成:用户名,组列表。无论什么时候,HDFS都必须会客户端进程访问的文件或目录foo做权限检查,

  • 如果用户名匹配foo的owner,那么校验owner权限;
  • 如果foo的group匹配group lists内的任一项,那么校验group权限;
  • 否则校验foo的其他权限;

如果权限校验失败,客户端操作失败。

User Identity

自 Hadoop 0.22 起,Hadoop 支持两种不同的操作模式来判断用户的身份,通过hadoop.security.authentication属性指定:

  • simple

    客户端进程的身份由主机操作系统判断。在类Unix系统上,用户名等同于whoami

  • kerberos

    客户端进程的身份由它的Kerberos凭证判断。比如,在一个Kerberized environment,一个用户可以通过kinit 功能来获取Kerberos ticket-granting-ticket (TGT) ,并使用klist来判断当前的委托人。当把一个Kerberos principal 映射到一个 HDFS 用户名,除了主要组件外的其他所有组件都被丢弃。例如,一个principal todd/foobar@CORP.COMPANY.COM 将以HDFS上的simple用户名todd进行操作。

不管是哪种模式,用户身份机制都是HDFS的外部机制。HDFS中没有用于创建用户、建立组、处理用户凭据的规定。

Group Mapping

一旦username被判定,如上,groups list将由group mapping service 判断,配置在hadoop.security.group.mapping属性。参见 Hadoop Groups Mapping 获取更多内容。

Permission Checks

每次HDFS操作都需要用户拥有指定权限(读,写,执行的组合),通过文件的 ownership,group membership or 其他权限进行授权。 一个操作会进行路径多个组件的权限检查,而不仅是最后一个组件。另外,一些操作依赖于路径owner的检查。

所有的操作都需要遍历访问(traversal access)。遍历访问需要对路径上的所有存在的组件拥有执行权限,最终路径组件除外。比如,任一访问 /foo/bar/baz 的操作,调用者需要拥有/, /foo and /foo/bar的可执行权限。

  • 如下表格描述了HDFS对路径每个组件的权限检查。
    • Ownership
      检查调用者是否path的owner。通常,改变元数据的ownership或permission的操作需要调用者是owner。
    • Parent
      当前请求path的父目录。比如,对于path /foo/bar/baz,parent 是 /foo/bar
    • Ancestor
      当前请求path最后存在组件。 比如,对于 path /foo/bar/baz,如果 /foo/bar存在的话,ancestor path 是 /foo/bar 。如果 /foo 存在,而 /foo/bar 不存在的话,ancestor path 是 /foo
    • Final
      当前请求path最终组件。比如,对于path /foo/bar/baz,final path 组件就是 /foo/bar/baz
    • Sub-tree
      如果path是一个目录,该目录和它的递归子目录。比如,对于 path /foo/bar/baz,有2个sub-directories buzboo,sub-tree 是 /foo/bar/baz/foo/bar/baz/buz/foo/bar/baz/boo
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] 如果调用使用overwrite配置,并且该路径已经存在文件,那么create操作只需要对最终路径组件拥有写权限即可。

[2] 如果设置了sticky bit ,对父目录写权限的检查操作,同样也会检查ownership。

[3] 调用 setOwner 来改变文件的拥有着需要 HDFS super-user 访问权限。变更组不需要HDFS super-user 访问权限,但是调用者必须是文件的拥有者并且是指定组的成员。

Understanding the Implementation

每个文件、目录操作都会将完全路径发送给NameNode,对每个操作都会沿着path进行权限检查。客户端框架隐式的将用户身份与到NameNode的连接关联,减少对现有客户端API的改动的需求。常见一种情况,当某文件的一个操作已经成功完成了,再操作的时候会失败,因为该路径上的文件、目录已经不存在了。举个例子,当客户端第一次开始读取一个文件,它向NameNode发出第一个请求,以发现文件的第一个块的位置。第二个请求查找其他的块可能会失败。另一方面,删除一个文件并不会撤回客户端对该文件的访问,该客户端已经知道该文件的块。通过添加权限,客户端对文件的访问可以在请求之间被撤回。同样,变更权限不会撤回客户端的访问,该客户端已经知道文件的块。

Changes to the 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; 将额外返回user, group and 路径相关的mode。

新文件、目录的mode受umask设置限制,umask设置是配置项。
当使用现有方法 create(path, …) (不带权限参数),新文件的 mode 是0666 & ^umask
当使用新方法 create(path, permission, …) (带权限参数 P) ,新文件的 mode 是 P & ^umask & 0666
当使用现有方法 mkdirs(path) (不带权限参数)创建一个新目录, 新目录的 mode 是0777 & ^umask
当使用新方法 mkdirs(path, permission) (带权限参数 P), 新目录的 mode 是 P & ^umask & 0777

Changes to the Application Shell

新操作:

  • chmod [-R] mode file ...
    仅文件的拥有着或super-user允许变更文件的mode。
  • chgrp [-R] group file ...
    调用chgrp的用户必须属于指定组,并且是文件的拥有者,或者是super-user。
  • chown [-R] [owner][:[group]] file ...
    文件的owner仅可以由super-user更改。
  • ls file ...
  • lsr file ...
    输出被重新格式化以显示 owner, group and mode。过时了,使用 -ls -R 替代。

The Super-User

谁启动NameNode,谁就是super-user。 super-user可以执行任意操作,权限校验从不失败。HDFS super-user 不必是NameNode 主机上的super-user,也不是说集群内的说有主机都需要有这个super-user。
如果在个人电脑上实验运行HDFS,为方便起见无须任何配置该用户即成为安装的super-user。

另外,管理员还可以通过配置参数标识一个特定组。该组内的成员也是super-users。

The Web Server

默认,web server的身份是一个可配置项。即,NameNode不知道真实用户的身份,但是web server以管理员选定的用户的身份(用户/组)行动。 除非选择的身份匹配super-user,部分命名空间是不可以被web server访问的。

ACLs (Access Control Lists)

除了传统的POSIX权限模型,HDFS还支持POSIX ACLs (Access Control Lists)。ACLs 对于实现区分用户、组的自然组织层次结构的权限需求非常有用。ACL提供了一个方法,可以给指定用户、组设置不同的权限,而不仅仅是文件的拥有着和所属组。

默认,ACLs的支持是关闭的,并且NameNode不允许创建ACLs。要开启ACLs的支持,在NameNode配置内设置dfs.namenode.acls.enabled为 true。

一个ACL由一系列ACL entries组成。每条ACL entry 命名了特定用户/组,并授于/拒绝 读、写、执行权限。比如:

   user::rw-
   user:bruce:rwx                  #effective:r--
   group::r-x                      #effective:r--
   group:sales:rwx                 #effective:r--
   mask::r--
   other::r--

ACL entries 由type,可选的 namepermission 组成。为了便于展示,‘:’ 用作分隔符。 在这个范例内,文件的owner有read-write权限,文件的group有read-execute权限,others有读取权限。因此,等同于设置文件的权限为654。

另外,有2个扩展ACL entries给用户 bruce 和组 sales,并全部赋予所有权限。mask 是一个特殊的ACL entry,过滤给所有命名的user entries 和命名的group entries 以及非命名的group entry的权限。 在范例内,mask仅有写权限,并且我们可以看到几个ACL entries的有效权限被相应的过滤了。

每个ACL都必要要有一个mask。如果在设置ACL的时候用户没有提供mask,那么会通过计算来自动插入,计算将被过滤的所有entries的权限的并集。

在拥有ACL的文件上运行 chmod 实际上改变了mask的权限。既然mask作为过滤器,这有效的约束了所有扩展ACLs的权限,而不仅是变更group entry并且可能会丢失其他扩展ACL entries。

模型还有效区分了“access ACL”“default ACL”
“access ACL”,定义权限检查期间强制执行的规则;“default 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的确切权限值将由mode参数进行过滤。考虑到默认umask 是 022,则新目录是755,新文件是644。mode参数给unnamed user (file owner), the mask and other过滤过滤拷贝过来的权限值。 使用这个特定范例ACL,并创建一个mod 755的子目录,该mode过滤器对最终结果没有影响。但是,如果我们考虑创建一个mode 644 的文件,mode过滤器会导致新文件的ACL接受unnamed user(file owner)的读写权限,mask的读权限,以及其他的读权限。 该mask意味着named user bruce 和 named group sales 的有效权限是只读。

注意,拷贝发生在创建新文件或子目录的时候。对父级默认ACL的后续修改不会影响存在的子级。

默认 ACL 必须拥有所有必要的ACL entries,包括unnamed user (file owner), unnamed group (file group) and other entries。当设置默认ACL的时候,如果用户没有指定其中某个entry,那么entries会自动插入,通过拷贝访问ACL相应的权限、如果没有访问ACL则拷贝permission bits来实现。默认ACL必须拥有mask。如上所属,如果没有指定会自动插入一个计算的值。

对拥有ACL的文件,权限的检查算法变更为:

  • 如果用户名匹配file owner,那么检查owner permission;

  • 否则如果用户名匹配named user entries之一,那么要检查这些权限,以mask权限过滤;

  • 否则如果组匹配groups list的成员,并且如果这些通过mask过滤的权限获取访问,那这些权限被使用;

  • 否则如果由一个named group entry 匹配groups list成员,并且如果这些通过mask过滤的权限获取访问,那这些权限被使用;

  • 否则如果文件所属组或任一 named group entry 匹配 groups list成员,但是访问没有被这些权限授权,那么访问被拒绝;

  • 其他情况下,文件的other权限会被测试。

最佳实践依赖传统的权限位来实现大多数权限需求,并定义较少数量的ACL来加强,用一些异常规则来扩充权限位。与只有权限位的文件相比,具有ACL的文件在NameNode中会增加内存开销。

ACLs File System API

新方法:
public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;
public void removeAclEntries(Path path, List<AclEntry> aclSpec) throws IOException;
public void public void removeDefaultAcl(Path path) throws IOException;
public void removeAcl(Path path) throws IOException;
public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException;
public AclStatus getAclStatus(Path path) throws IOException;

ACLs Shell Commands

  • hdfs dfs -getfacl [-R] <path>

    显示文件/目录的ACL。如果一个目录拥有默认ACL,那么 getfacl还会显示默认ACL。

  • hdfs dfs -setfacl [-R] [-b |-k -m |-x <acl_spec> <path>] |[--set <acl_spec> <path>]

    设置文件/目录的ACL。

  • hdfs dfs -ls <args>

    ls 会在拥有ACL的文件、目录的权限string上附加一个‘+’字符。

参考 File System Shell 文档获取命令的全部内容。

Configuration Parameters

  • dfs.permissions.enabled = true

如果是,则使用这里描述的权限系统。如果否,关闭权限检查,但是其他行为不变。从一个参数值切换到其他值不会改变mode、文件或目录的owner or group。无论权限是开还是关,chmodchgrpchown and setfacl 总是会检查权限。 这些功能仅在权限上下文有用,因此不存在向后兼容问题。此外,这允许管理员可靠的设置所有者和权限,在打开常规权限检查前。

  • dfs.web.ugi = webuser,webgroup

web server使用的用户名。设置为super-user允许所有客户端看到任何内容。改为其他未使用的身份允许web客户端仅可以查看"other"权限可见的内容。其他将其他组添加到逗号分隔列表内。

  • dfs.permissions.superusergroup = supergroup

super-users 的组。

  • fs.permissions.umask-mode = 0022

当创建文件和目录时使用的 umask 。对于配置文件,可以使用十进制值 18。

  • dfs.cluster.administrators = ACL-for-admins

集群的管理员被配置为ACL。这控制谁可以访问HDFS默认的servlets 等。

  • dfs.namenode.acls.enabled = true

设置为true,开启HDFS ACLs (Access Control Lists)的支持。默认,ACLs是关闭的。当ACLs关闭的时候,NameNode拒绝所有设置ACL的企图。 .

  • dfs.namenode.posix.acl.inheritance.enabled

设置为true,开启 POSIX风格的ACL继承。默认开启。当它被启动时,并且create请求来自于兼容客户端,NameNode会从父目录应用默认ACL来创建mode并忽视客户端umask。如果没有默认ACL,它将应用客户端umask。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351