多读书多实践,勤思考善领悟

大数据hadoop之 二十四.Hive的安全

本文于1712天之前发表,文中内容可能已经过时。

一 概述

在了解Hive的安全机制之前,我们需要首先清楚Hadoop的安全机制以及Hadoop的历史,Hadoop起源于Apache Nuch的子项目.在那个时代以及整个早期原型时代,功能性需要比安全性需求优先级要高.分布式系统的安全问题要比正常情况下更加复杂,因为不同机器上的多个组件需要相互进行通信.

Hadoop的安全性近期有了许多变化,其中主要是对Kerberos安全认证的支持,还包括其他一些问题的修复.Kerberos允许客户端和服务器端相互认证.客户端的每次请求中都会带有凭证(ticket)信息.在TaskTracker上执行的任务(task)都是由执行任务(job)的用户来执行的.用户无法通过设置hadoop.job.ugi属性的值来模拟其他人来执行任务.为了达到这个目的,所有的Hadoop组件从头到尾都要使用kerberos安全认证.

Hive在Hadoop引入Kerberos支持之前就已经存在了,而且Hive目前还没有完全和Hadoop的安全改变相融合.例如,Hive元数据存储链接可能是直接连接到一个JDBC数据库或者通过Thrift进行链接,这些都是要用用户身份进行各种操作.像HiverService这样的基于Thrift的组件还是要冒充他人来执行.Hadoop的文件用户权限模型(也就是对于一个文件分为用户 组 和其他3层权限)和很多其他数据库中用户权限模型具有很大的差异,数据库中通常是对使用字段级别进行授权和权限回收操作来进行权限控制的.

和Hadoop安全功能相结合

Hive v0.70增加了和Hadoop安全功能的结合,这意味着,当Hive提交到安全集群的JobTracker上时,将使用合适的认证处理过程。用户权限可以被授予也可以被回收。

使用Hive进行验证

如果文件和文件夹是多个用户共同拥有,那么文件的权限就变得非常重要。HDFS中文件目录权限和Unix中的模式非常类似,都包含有3层:用户、组和其他。同时具有3种权限:可读、可写和可执行。Hive中有一个配置变量hive.files.umask.value来定义对于新创建的文件设置的默认权限的umask值,也就是掩码字节数。

1
2
3
4
<property>
<name>hive.files.umask.value</name>
<value>0002</value>
</property>

同时,当属性hive.metastore.authorization.storage.checks的值为true时,如果用户没有权限删除表底层的文件,Hive就会阻止用户来删除这样的表。这个参数的默认值是false。其应该设置为true的:

1
2
3
4
<property>
<name>hive.metastore.authorization.storage.checks</name>
<value>true</value>
</property>

当在安全模式下执行时,Hive元数据存储要尽可能的将hive.metastore.execute.setugi设置为true。

1
2
3
4
<property>
<name>hive.metastore.execute.setugi</name>
<value>false</value>
</property>

Hive中的权限管理

Hive v0.7.0增加了HiveQL进行授权设置的功能。默认授权模块是不开启的,需要将如下的属性设置为true,才能开启授权:

1
2
3
4
5
6
7
8
9
<property>
<name>hive.security.authorization.enabled</name>
<value>true</value>
</property>

<property>
<name>hive.security.authorization.createtable.owner.grants</name>
<value>ALL</value>
</property>

默认情况下,hive.security.authorization.createtable.owner.grants的值是null,这使得用户无法访问自己的表,因此,我们也要给予表创建者对应的权限才能访问自己创建的表。

用户、组和角色

可以对用户(user)、组(group)、或者角色(role)授予权限或者回收权限。

1
2
hive> set hive.security.authorization.enabled=true;
hive> create table authorization_test(key int, value string); --->会报权限错误

我们使用的用户没有在default数据库下创建表的权限。我们可以对多个实体进行授权。第一个实体就是用户(user),Hive中的用户就是用户的系统用户名。我们可以确定其名称,并按照如下语句将在default数据库下的创建表(create)权限授予这个用户:

1
2
3
hive> set system:user.name;
hive> grant create on database default to user edward;
hive> create table authorization_test(key int, value string);

通过show grant查看授权结果

1
2
3
4
5
6
7
hive> show grant user edward on database default;
database default
principalName edward
principalType USER
privilege Create
grantTime Mon Mar 18 17:37:00 EDT 2019
grantor edward

可以基于组级别授权,Hive中组和用户的住POSIX组是等价的。

1
2
3
4
hive> create table authorization_test_group(a int, b int);
hive> select * from authorization_test_group; ----> 权限异常
hive> grant select on table authorization_test_group to group edward;
hive> select * from authorization_test_group;

也可以使用角色(role)。用户可以放置在角色中同时可以为角色进行授权。角色关系灵活,因为和组不一样,组由系统外部控制,角色是由Hive内部控制:

1
2
3
4
5
6
hive> create table authorization_test_role(a int, b int);
hive> select * from authorization_test_role; ----> 权限异常
hive> create role users_who_can_select_authentication_test_role;
hive> grant role users_who_can_select_authentication_test_role to user edward;
hive> grant select on table authorization_test_role to role users_who_can_select_authentication_test_role;
hive> select * from authorization_test_role;

Grant和Revoke权限

1
2
3
4
5
6
7
8
9
10
权限						       	描述
ALL 赋予所有的权限
ALTER 有修改表结构的权限
CREATE 有创建表的权限
DROP 有删除表或表中的分区权限
INDEX 创建表索引的权限
LOCK 开启并发后,锁定和解锁定表的权限
SELECT 查询表或者分区中数据的权限
SHOW DATABASE 查看所有数据库的权限
UPDATE 向表或者分区中插入或加载数据的权限

以create权限为例:

1
2
3
4
5
6
7
hive> set hive.security.authorization.enabled=true;
hive> create database edsstuff;
hive> use edsstuff;
hive> create table a (id int); --->权限异常
hive> grant create on database edsstuff to user edward;
hive> create table a (id int);
hive> create external table a (id int);

同样,我们可以通过如下命名授予ALTER权限:

1
2
3
hive> alter table a replace columns(a int, b int); --->权限异常
hive> grant alter on table a to user edward;
hive> alter table a replace columns(a int, b int);

注意:为分区表新增分区的操作是不需要alter权限的:

1
hive> alter table a_part_table add partition(b=5);

往表中加载数据的话需要使用UPDATE权限:

1
2
3
hive> load data inpath '${env:HIVE_HOME}/NOTICE' into table a_part_table partition(b=5);	---> 权限异常
hive> grant update on table a_part_table to user edward;
hive> load data inpath '${env:HIVE_HOME}/NOTICE' into table a_part_table partition(b=5);

删除表或者分区需要drop权限:

1
hive> alter table a_part_table drop partition(b=5);	--->权限异常

从表或者分区中查询数据需要select权限

1
2
3
hive> select id from a_part_table;	--->权限异常
hive> grant select on table a_part_table to user edward;
hive> select id from a_part_table;

授予全部的权限:

1
hive> grant all on table a_part_table to user edward;

分区级别的权限

Hive中分区表非常常见。默认是在表级别授予权限,不过,同样可以在分区级别进行授权。为达到这个目标,只需要将表属性PARTITION_LEVEL_PRIVILEGE设置为TRUE即可:

1
2
3
4
5
6
7
8
9
10
11
hive> create table authorize_part(key int, value string) partitioned by (ds string);
hive> alter table authorize_part set tblproperties("PARTITION_LEVEL_PRIVILEGE"="TRUE"); --->权限异常
hive> grant alter on table authorize_part to user edward;
hive> alter table authorize_part set tblproperties("PARTITION_LEVEL_PRIVILEGE"="TRUE");
hive> grant select on table authorize_part to user edward;
hive> alter table authorize_part add partition(ds='3');
hive> alter table authorize_part add partition(ds='4');
hive> select * from authorize_part where ds = '3';
hive> revoke select on table authorize_part partition(ds='3') from user edward;
hive> select * from authorize_part where ds = '3'; --->权限异常
hive> select * from authorize_part where ds = '4';

自动授权

用户经常会期望创建表后不再执行烦人的授权命令,就可以具有相关的权限,而直接去执行后续的查询等等。早期,用户可能需要具有ALL权限才可以,不过现在为默认情况制定更细节的权限。
属性hive.security.authorization.createtable.owner.grants中可以定义为创建表的用户自动授予这张表的指定的权限。比如下面的例子为用户自动授予对其所创建表的表的select和drop权限:

1
2
3
4
<property>
<name>hive.security.authorization.createtable.owner.grants</name>
<value>select, drop</value>
</property>

类似的,可以在创建表时自动授予指定用户指定的权限。属性hive.security.authorization.createtable.user.grants控制这个行为。
比如下面的例子展示了Hive管理员账号admin1和用户edward默认授予所有表的读权限,而user1只有创建表的权限。

1
2
3
4
<property>
<name>hive.security.authorization.createtable.user.grants</name>
<value>admin,edward:select;user1:create</value>
<property>

对于组(group)和角色(role)同样具有类似的属性来控制自动授予的权限。对于组,该属性名为hive.security.authorization.createtable.group.grants;对于角色,这个属性是hive.security.authorization.createtable.role.grants。这些属性的值的形式和前面介绍的是相同的。