环境:CDH6.3.1,Centos7.5

photo

上一篇记录的是kerberos。是用来管理用户身份*即用户身份认证

Sentry,用户身份和权限的映射关系管理 即授权。
CDH的介绍是:Sentry 服务存储身份验证政策元数据并为客户端提供对该元数据的并发安全访问。

我理解的kerberos+sentry = 用户验证+权限管理。搭配组合使用来做多租户的权限分配。 可以管理用户读那些hive表,和那些hdfs路径下的文件。

一.CM添加Sentry服务及配置

1.在CM中添加服务。Sentry sentry

给服务器分配sentry角色 sentry

需要生成一个sentry的数据库,我这里sentry数据库和其他服务放在了一起都在h1上,数据库名字自定义,我这里数据库和用户都叫sentry sentry

下面两步没有截图。略过了。

2.添加好sentry服务下面开始设置sentry:

Hive的设置,将图中两项勾选去掉 sentry

第二步 将Hive服务的Sentry勾上,默认是none sentry

然后重启hive的过时配置即可。

3.设置hdfs的控制列表和sentry同步

紧接着,开启HDFS角色的acl(这里主要控制用户访问的HDFS目录,因为在生产环境中会指定一些目录是该用户可以访问的,而其他一些目录该用户访问不了)

以下两项勾选。 sentry

然后重启hdfs的过期配置,并勾选重新部署客户端配置

4.接下来。生成hive.keytab

在KDC服务器上执行以下命令,将集群的所有机器的keytab汇总到一个文件中:

首先在Kerberos数据库中创建principal:kadmin.local -q "addprinc -randkey hive/h$i.cat.com@CAT.COM"

批量生成命令:for i in {1..4}; do sudo kadmin.local -q "addprinc -randkey hive/h$i.cat.com@CAT.COM ";done

然后,在当前目录下生成hive.keytab文件:kadmin.local -q "xst -norandkey -k hive.keytab hive/h$i.cat.com@CAT.COM"

批量生成命令:for i in {1..4};do sudo kadmin.local -q "xst -norandkey -k hive.keytab hive/h$i.cat.com@CAT.COM";done

然后在集群中一个节点修改/etc/hive/conf/hive-site.conf

添加以下内容。指定keytab的路径

1
2
3
4
  <property>
  <name>hive.metastore.kerberos.keytab.file</name>
  <value>/etc/hive/conf/hive.keytab</value>
  </property>

将修改后的hive-site.conf发送到集群中的其他机器的/etc/hive/conf目录下(h1,h2,h3,h4)

for i in {1..4};do scp hive-site.conf h$i:/etc/hive/conf;done

将上面生成的keytab发给集群的其他所有服务器(h1,h2,h3,h4)

for i in {1..4};do scp hive.keytab h$i:/etc/hive/conf;done

然后修改keytab的权限。

for i in {1..4}; do ssh h$i "cd /etc/hive/conf; chmod 400 hive.keytab; chown hive:hadoop hive.keytab"; done

  • 注:由于 keytab 相当于有了永久凭证,不需要提供密码(如果修改 kdc 中的 principal 的密码,则该 keytab 就会失效),所以其他用户如果对该文件有读权限,就可以冒充 keytab 中指定的用户身份访问 hadoop,所以 keytab 文件需要确保只对 owner 有读权限(0400)

二.权限测试及验证

创建系统用户,user1,user2,上一篇说过,建立账户要给所有的机器都创建。考虑到用户的任务分发问题,会报错。

1
2
3
4
5
6
7
8
[root@h1 ~]# useradd user1
[root@h1 ~]# useradd user2
[root@h2 ~]# useradd user1
[root@h2 ~]# useradd user2
[root@h3 ~]# useradd user1
[root@h3 ~]# useradd user2
[root@h4 ~]# useradd user1
[root@h4 ~]# useradd user2

在KDC上创建Kerberos用户

1
2
sudo kadmin.local -q "addprinc user1"
sudo kadmin.local -q "addprinc user2"

使用keytab 登陆kerberos hive用户

1
2
3
[root@h1 ~]#kinit -kt hive.keytab hive/h1.cat.com
[root@h1 ~]#hive

创建测试数据库

1
2
3
create database db1;
create database db2;

在数据库中创建表 在db1中创建table1,在db2中创建table1和table2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
create table db1.table1 (
name STRING, age STRING
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
create table db2.table1 (
name STRING, age STRING
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
create table db2.table2 (
name STRING, age STRING
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

1
2
3
4
5
6
7
8
cat test.csv 
leo,19
lilei,23
jack,25
tony,28
eric,18
lucy,16

导入数据

1
2
3
4
load data local inpath '/home/user1/test.csv' overwrite into table db1.table1;
load data local inpath '/home/user1/test.csv' overwrite into table db2.table1;
load data local inpath '/home/user1/test.csv' overwrite into table db2.table2;

用户授权。给user1,user2授权数据库权限

使用Hive client授权报错。 上面已经用kinit -kt hive.keytab hive/h1.cat.com 切换为hive用户了,hive还是没有权限操作。

1
2
3
4
5
6
hive> create role user1_role;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Current user : hive is not allowed to add roles. User has to belong to ADMIN role and have it as current role, for this action.
hive> GRANT ALL ON DATABASE db1 TO ROLE user1_role;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Permission denied: Principal [name=hive, type=USER] does not have following privileges for operation GRANT_PRIVILEGE [[SELECT with grant, INSERT with grant, UPDATE with grant, DELETE with grant] on Object [type=DATABASE, name=db1]]
hive> GRANT ROLE user1_role TO GROUP user1;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Invalid principal type in principal Principal [name=user1, type=GROUP]

hive没有权限做授权,看网上资料用的是beeline,然后成功。

1
2
3
4
5
6
7
8
9

create role user1_role;
GRANT ALL ON DATABASE db1 TO ROLE user1_role;
GRANT ROLE user1_role TO GROUP user1;

create role user2_role;
GRANT ALL ON DATABASE db2 TO ROLE user2_role;
GRANT ROLE user2_role TO GROUP user2;

sentry

验证User1只有db1和default的权限(default是默认的自带库) sentry

User2只有db2和default的权限 sentry

然后验证hdfs 权限 User1只能查看db1.db表下面的数据文件 sentry

同理use2只能查看db2.db下面的数据。 sentry

三.问题与总结:

1.当使用hive cli的时候,会显示所有表,而beeline只会显示有权限的表,但hive显示没有权限的表当查询的时候也会报没有权限的错误。

例如。User2用户使用user1的db1。会报以下错误。没有权限读取元数据的hdfs目录数据

1
2
3
4
5

FAILED: SemanticException Unable to determine if hdfs://h1.cat.com:8020/user/hive/warehouse/db1.db/table1 
is encrypted: org.apache.hadoop.security.AccessControlException: Permission denied: user=user2, access=READ, 
inode="/user/hive/warehouse/db1.db/table1":hive:hive:drwxrwx--

sentry

2.这里用keytab登陆hive报错。 hive> [root@h1 ckinit -kt hive.keytab hive/h1.cat.com
kinit: Password incorrect while getting initial credentials

  • 注意。修改配置,和重启服务会提示keytab失效,报以下错误,需要生成,然后分发即可。

3.连接beeline命令 !connect jdbc:hive2://localhost:10000/;principal=hive/h1@CAT.COM