HDFS权限

HDFS权限

一、HDFS权限简介

Hdfs的权限管理分为2大部分:

  • 第一部分类似于Linux的基本权限管理,也就是粗粒度将管理对象分为user、group和other三类去进行权限的管理。
  • 第二部分是ACL方式的权限管理,也是更加细粒度的权限管理,可以精确控制到某个user与某个group具有的对应权限上。

注:hadoop2.4.0版本开始支持hdfs的ACL

二、HDFS 基本权限管理

2.1 初始目录权限

当我们创建文件或者目录的时候可以指定权限,没有指定的话就会使用默认的权限。
文件默认权限:666
目录默认权限:777

2.2 修改默认权限配置uMask

作用:客户端自己主宰文件或目录的初始创建权限
1)CDH配置图解

fs.permissions.umask-mode=022

在这里插入图片描述

详解:022:0表示对owner没有限制,2表示对group不允许有写权限,2表示对other不允许有写权限。

实际计算方式为:应用客户端配置的umask其实就是拿用户设置的权限减去上述umask权限,就得到文件或目录的最终权限了。如创建目录,默认777权限,然后减去umask权限022就等于755,即默认情况下owner拥有读写和可执行权限,owner所在group拥有读和可执行权限,other拥有读和可执行的权限

三、HDSF ACL权限管理

解决什么问题:假设,我们有一个HDFS目录/user/tao/xt-data,它目前的权限为drwxrwxr-x tao supergroup。我希望让另一个用户Hbase(不属于任何group)对该目录有rwx的权限,这可以使用ACL权限解决

3.1 开启HDFS ACL

<property>
  <name>dfs.namenode.acls.enabled</name>
  <value>true</value>
</property>

3.2 基本命令操作

1)获取目录和文件的ACL信息

hdfs dfs -getfacl [-R] /tmp

2)设置目录和文件的ACL信息

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

命令详解:

-R: 遍历路径里的所有文件。
-b: 撤销除了基本用户和组权限以外的所有权限。
-k: 撤销默认的ACL设置。
-m: 添加新的权限来使用此ACL。不影响现有权限。
-x: 只撤销指定的ACL。
<acl_spec>: 逗号分隔的ACL权限列表。
--set: 使用该选项指定的路径完全取代现有的ACL。之前的ACL将不再适用。

3)举例

1.为目录添加访问权限
hadoop fs -setfacl -m user:abc:r-x /user/hadoop
2.为目录添加可继承的权限
hadoop fs -setfacl -m default:user:abc:r-x,default:group:xxx:r-x,default:other::r-x /user/hadoop
3.删除目录权限
hadoop fs -setfacl -b /user/hadoop
4.删除特定权限,保留其他权限
hadoop fs -setfacl -x user:abc:rwx /user/hadoop

3.3 详解ACL属性值

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

详解:

第一部分由固定的类型名构成,有user,group,other,mask,default等选项。mask条目会过滤掉所有命名的用户和用户组,以及未命名的用户组权限。第二部分可以指定类型名称,如用户名,用户组名等(other类型不需要名称),这部分是可选项,若不指定特定的用户名或用户组,则表示只对该文件属主或目录的用户组生效。第三部分就是权限位。 若该条规则应用到foo文件,foo文件的属主有读写权限,foo文件的用户组有只读和执行权限(对于目录),其他用户也是只读权限;但bruce用户的权限经过mask过滤后只有只读权限,sales组也是只读权限。
default类型是一个特殊的类型,且只应用在目录上,用于在创建子目录和文件时为其应用该默认的ACL规则。权限复制发生在文件产生之时,在这之后对父级目录的ACL操作,不会影响子目录已存在的ACL规则。 另外每个ACL规则都有mask条目,如果用户在设置ACL时没有显式声明,那么系统会自动地添加一条mask规则。在含有ACL规则的文件上通过chmod变更权限会改变mask值。因为mask要作为一个过滤器来更有效地限制所有的扩展ACL条目,如果仅仅改变组条目,这会导致Other部分的ACL规则出现缺漏

3.4 默认ACL创建

可以为某个目录设置一个默认的ACL权限,使得以后在该目录中新建文件或者子目录时,新建的文件/目录的ACL权限都是之前设置的default ACLs。

hadoop dfs -setfacl -m default:user:hbase:rwx /user/tao

四、ACL 与 普通权限管理的优先级

权限检查会在每次操作时进行,客户端会隐式地传送用户身份到Namenode。当客户端开始读取某一文件时,它会首先向Namenode发送请求来查找该文件的第一个block,查找该文件额外blocks的请求可能会失败。因为权限的缘故,所以客户端对文件的访问权限可能会在请求之间被收回。更改权限并不会撤销已知文件块的客户端访问权限。

权限判断的前后顺序通过以下代码实现


  private void check(INodeAttributes inode, String path, FsAction access
      ) throws AccessControlException {
    if (inode == null) {
      return;
    }
    final FsPermission mode = inode.getFsPermission();
    final AclFeature aclFeature = inode.getAclFeature();
    if (aclFeature != null) {
      // It's possible that the inode has a default ACL but no access ACL.
      int firstEntry = aclFeature.getEntryAt(0);
      if (AclEntryStatusFormat.getScope(firstEntry) == AclEntryScope.ACCESS) {
        checkAccessAcl(inode, path, access, mode, aclFeature);
        return;
      }
    }
    if (getUser().equals(inode.getUserName())) { //user class
      if (mode.getUserAction().implies(access)) { return; }
    }
    else if (getGroups().contains(inode.getGroupName())) { //group class
      if (mode.getGroupAction().implies(access)) { return; }
    }
    else { //other class
      if (mode.getOtherAction().implies(access)) { return; }
    }
    throw new AccessControlException(
        toAccessControlString(inode, path, access, mode));
  }

从代码即可看出,权限首先会判断ACL规则,然后再判断权限位,根据先用户,再组,再其他的顺序进行。

  • 首先检查是否为超级用户(在之前的步骤)
  • 再次检查用户是否一致,然后验证用户权限位
  • 再次检查文件组名在用户所在的用户组列表中,然后验证用户组权限位
  • 最后检查其他组权限位
  • 否则抛出权限异常,访问失败

当开启了ACL后,检查用户权限的流程变更为如下:

  1. 当用户名和文件属主完全匹配时,则检验用户权限
  2. 当用户名匹配了文件ACL规则中的某个User条目中的用户名时,检查该条目下的用户权限与mask掩码计算后的权限是否合法
  3. 当文件的组名匹配了该用户的用户组列表中的某个成员,检查该条目下的Group权限与mask掩码计算计算后的权限是否合法
  4. 如果ACL规则中的命名用户组存在于该用户组列表中,并且该条目下的Group权限与mask掩码计算计算后的权限验证成功,则会使用该ACL条目中的Group权限
  5. 如果文件组名或命名的组ACL规则匹配了用户的用户组,但是并未通过权限检查,那么访问被禁止
  6. 最后检查其他权限位

详细的代码实现可以查看 FSPermissionChecker#checkAccessAcl 方法

五、总结

  1. 为不同的文件目录设置属主和权限位,将数据通过不同的用户权限隔离开来。
  2. 对于用户间共享的数据,优先使用用户组权限实现。一般来说,不同的目录对应到不同的用户组。在设置了用户组权限的目录下,新建文件和子目录会继承当前目录的用户组和权限位。
  3. 由于只设置需要共享目录的权限,该共享目录的上级或父目录需要通过递归方式添加只读ACL。这样可以避免开通不必要的其他组权限,导致数据权限出现安全隐患。
  4. 对于特定的共享目录,用户组中的用户可能有些有只读权限,有些是读写权限。这种情况下,用户的写权限通过ACL额外指定。所有用户的读权限通过用户组来指定接口
  5. 如果上述权限还需要在子目录中继承下去,则需要设定用户写权限的default规则(尽量少用,做到一个账号写,多个账号读即可)。
  6. 用户组名与目录名绑定,这样可以方便在有其他人需要访问该目录时,可以通过变更用户组成员解决。

使用ACL的最佳实践: 使用传统的权限位来实现最大的权限管理需求,对一些特殊的权限规则定义少量的ACLs来加强权限控制。因为相比于使用权限位,使用ACL会在NameNode端占用额外的内存。故总体的原则是,在能使用组解决问题时,尽量使用组,特别是只读场合和需要权限继承的场景

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页