hive 权限管理

        hive做为table的存储层,spark sql,mapreduce, Presto 等等通过 Hive's HCatalog API 访问元数据信息, 进而访问hdfs数据, 此时要对hdfs访问做权限控制(hdfs 默认已经处理),元数据访问需要做权限控制。      hive sql 执行引擎, hive的一个非常普遍的用法,主要针对sql的用户和BI工具       

            (1)hive 客户端用户 (官方建议抛弃)     (2)ODBC/JDBC 和 HiveServer2 Api(Beeline CLI)               

           HiveServer2是一个服务,支持客户端不使用Hive脚本进行执行查询,HiveServer2继承了HiveServer1,HiveServer1已经过时!

            HiveServer2其实就是一个远程客户端执行查询的和检索的一个服务接口,目前是基于Thrift RPC实现的,是HiveServer的提高版本,支持多客户端并发查询和认证,它被提供是为了更好的开放客户端API,例如JDBC和ODBC(言外之意就是远程的hive client执行查询都需要连接到HiveServer2之上)       针对上面的用例hive官方提供三种权限控制: 基于元数据存储、 基于sql标准、 默认的hive授权。选中方案 HiveServer2中基于SQL标准的授权为主,包含Metastore Server中基于存储的授权(Metastore Server中基于存储的授权可选),先上图:

Metastore

Metastore组件:它是元数据服务组件,hive元数据集中存放地。Metastore组件包括两个部分:metastore服务和后台数据的存储。后台数据存储的介质就是关系数据库,例如mysql数据库。Metastore服务是建立在后台数据存储介质之上,并且可以和hive服务进行交互的服务组件,默认情况下,metastore服务和hive服务是安装在一起的,运行在同一个进程当中。也可以把metastore服务从hive服务里剥离出来,metastore独立安装在一个集群里,hive远程调用metastore服务,这样就可以把元数据这一层放到防火墙之后,客户端访问hive服务,就可以连接到元数据这一层,从而提供了更好的管理性和安全保障。使用远程的metastore服务,可以让metastore服务和hive服务运行在不同的进程里,这样也保证了hive的稳定性,提升了hive服务的效率。

Hive中metastore(元数据存储)的三种方式:

1)内嵌Derby方式(默认方案)   2)Local方式     3)Remote方式

Local方式

以本地Mysql数据库为例,配置文件 hive-site.xml 中jdbc URL、驱动、用户名、密码等属性值配置如下:

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://eagle80:3306/hive?createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

<property>

<name>javax.jdo.option.ConnectionDriverName</name>

<value>com.mysql.jdbc.Driver</value>

<description>Driver class name for a JDBC metastore</description>

</property>

<property>

<name>javax.jdo.option.ConnectionUserName</name>

<value>root</value>

<description>username to use against metastore database</description>

</property>

<property>

<name>javax.jdo.option.ConnectionPassword</name>

<value>123456</value>

<description>password to use against metastore database</description>

</property>

<property>

<name>hive.metastore.warehouse.dir</name>

<value>/user/hive/warehouse</value>

<description>location of default database for the warehouse</description>

</property>

ps:需要把mysql的驱动包copy到目录 <HIVE_HOME>/lib 中

如果是第一次需要执行初始化命令:schematool -dbType mysql -initSchema

配置完成之后启动元数据服务,然后使用hive进入shell进行交互式查询。

Remote方式

客户端配置都在一个 hive-site.xml 中,属性值配置如下:

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://eagle80:3306/hive?createDatabaseIfNotExist=true</value>

</property>

<property>

<name>javax.jdo.option.ConnectionDriverName</name>

<value>com.mysql.jdbc.Driver</value>

</property>

<property>

<name>javax.jdo.option.ConnectionUserName</name>

<value>root</value>

</property>

<property>

<name>javax.jdo.option.ConnectionPassword</name>

<value>123456</value>

</property>

<property>

<name>hive.metastore.schema.verification</name>

<value>false</value>

</property>

<property>

<name>hive.metastore.uris</name>

<value>thrift://eagle80:9083</value>

</property>

hive metastore 服务端启动命令:

hive --service metastore 启动元数据服务

三种部署方式区别总结:

  • 内嵌模式使用的是内嵌的Derby数据库来存储元数据,也不需要额外起Metastore服务。这个是默认的,配置简单,但是一次只能一个客户端连接,适用于用来实验,不适用于生产环境。
  • 本地元存储和远程元存储都采用外部数据库来存储元数据,目前支持的数据库有:MySQL、Postgres、Oracle、MS SQL Server.在这里我们使用MySQL。
  • 本地元存储和远程元存储的区别是:本地元存储不需要单独起metastore服务,用的是跟hive在同一个进程里的metastore服务。远程元存储需要单独起metastore服务,然后每个客户端都在配置文件里配置连接到该metastore服务。远程元存储的metastore服务和hive运行在不同的进程里。

授权模式概述

1、旧的默认Hive授权(传统模式)

Hive旧默认授权(在Hive 2.0.0之前是默认授权)是早期版本的Hive中可用的授权模式。但是,此模式没有完整的访问控制模型,因此未解决许多安全漏洞。例如,未定义为用户授予权限所需的权限,并且任何用户都可以授予自己对表或数据库的访问权限。

此模型类似于基于SQL标准的授权模式,因为它提供基于grant / revoke语句的访问控制。但是,访问控制策略与基于SQL标准的授权不同,并且它们不兼容。

2、 Metastore Server中基于存储的授权

通过在Metastore Server中启用基于存储的授权, 会控制元数据对象(如数据库,表和分区)上的元数据访问,它会检查您是否拥有文件系统上相应目录的权限。

Metastore Server中基于存储的授权

<property>

<name>hive.security.metastore.authorization.manager</name>

<value>org.apache.hadoop.hive.ql.security.authorization.DefaultHiveMetastoreAuthorizationProvider</value>

</property>

<property>

<name>hive.security.metastore.authorization.auth.reads</name>

<value>true</value>

</property>

<property>

<name>hive.security.metastore.authenticator.manager</name>

<value>org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator</value>

</property>

<property>

<name>hive.metastore.pre.event.listeners</name>

<value> org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener</value>

</property>

3、 HiveServer2中基于SQL标准的授权

尽管基于存储的授权可以在数据库,表和分区级别提供访问控制,但它无法控制更精细级别的授权,例如列和视图,因为文件系统提供的访问控制位于目录和文件级别。细粒度访问控制的先决条件是数据服务器,它只能提供用户需要访问的列和行。在文件系统访问的情况下,整个文件被提供给用户。HiveServer2满足这个条件,因为它有一个理解行和列的API(通过使用SQL),并且只能提供SQL查询所要求的列和行。

基于SQL标准的授权 (在Hive 0.13.0中引入)  可用于实现细粒度访问控制。它基于授权的SQL标准,并使用熟悉的grant / revoke语句来控制访问。需要通过HiveServer2配置启用它。 

请注意,对于Hive命令行,禁用基于SQL标准的授权。这是因为在Hive中使用访问控制策略的Hive命令行无法进行安全访问控制,因为用户可以直接访问HDFS,因此他们可以轻松绕过基于SQL标准的授权检查,甚至完全禁用它。禁用此功能可避免给用户带来错误的安全感。

<property>

<name>hive.security.authorization.enabled</name>

<value>true</value>

<description>enable or disable the Hive client authorization</description>

</property>

<property>

<name>hive.security.authorization.createtable.owner.grants</name>

<value>ALL</value>

<description>

The privileges automatically granted to the owner whenever a table gets created.

An example like "select,drop" will grant select and drop privilege to the owner

of the table. Note that the default gives the creator of a table no access to the

table (but see HIVE-8067).

</description>

</property>

SQL Standards Based Authorization in HiveServer2默认提供两种角色:public和admin,所有用户默认属于角色public,而授权则必须是具有角色admin的用户才可以完成(普通用户仅可以将自己获得的权限授权给其它用户),因此我们必须添加至少一个用户拥有角色admin

<property>

<name>hive.users.in.admin.role</name>

<value>root</value>

<description>

Comma separated list of users who are in admin role for bootstrapping.

More users can be added in ADMIN role later.

</description>

</property>

<property>

<name>hive.semantic.analyzer.hook</name>

<value>com.sunlands.eagle.etl.AdminHive</value>

<description/>

</property>

<property>

<name>hive.server2.enable.doAs</name>

<value>false</value>

<description>

Setting this property to true will have HiveServer2 execute

Hive operations as the user making the calls to it.

</description>

</property>

<property>

<name>hive.metastore.authorization.storage.checks</name>

<value>true</value>

<description>

Should the metastore do authorization checks against the underlying storage (usually hdfs)

for operations like drop-partition (disallow the drop-partition if the user in

question doesn't have permissions to delete the corresponding directory

on the storage).

</description>

</property>

<property>

<name>hive.security.authorization.manager</name>

<value>org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdConfOnlyAuthorizerFactory</value>

<description>

The Hive client authorization manager class name. The user defined authorization class should implement

interface org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider.

interface org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider.

</description>

</property>

<property>

<name>hive.security.authenticator.manager</name>

<value>org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator</value>

<description>

hive client authenticator manager class name. The user defined authenticator should implement

interface org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider.

</description>

</property>

<!-- HiveServer2中基于SQL标准的授权 与 Metastore Server中基于存储的授权 共有配置 -->

<property>

<name>hive.security.metastore.authorization.manager</name>

<value>org.apache.hadoop.hive.ql.security.authorization.StorageBasedAuthorizationProvider,org.apache.hadoop.hive.ql.security.authorization.MetaStoreAuthzAPIAuthorizerEmbedOnly</value>

</property>

超级权限

此时hive已经开启了权限管理的功能,但是所有的用户都拥有给自己甚至别人赋权的能力。为了安全起见(这种安全机制只是为了避免误操作)我们只需要一个超级管理员用户拥有给别人赋权的能力。所以接着我们写一个类用来控制用户的赋权权限。

package com.sunlands.eagle.etl                                                                                                                                 

import org.apache.hadoop.hive.ql.parse.ASTNode;                                

import org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook;           

import org.apache.hadoop.hive.ql.parse.HiveParser;                             

import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;        

import org.apache.hadoop.hive.ql.parse.SemanticException;                      

import org.apache.hadoop.hive.ql.session.SessionState;                                                                                                

public class AdminHive extends AbstractSemanticAnalyzerHook {                   

    private static String admin = "root";                                                                                                          

    @Override                                                                  

    public ASTNode preAnalyze(HiveSemanticAnalyzerHookContext context,  ASTNode ast) throws SemanticException {                            

        switch (ast.getToken().getType()) {                                    

        case HiveParser.TOK_CREATEDATABASE:                                    

        case HiveParser.TOK_DROPDATABASE:                                      

        case HiveParser.TOK_CREATEROLE:                                        

        case HiveParser.TOK_DROPROLE:                                          

        case HiveParser.TOK_GRANT:                                             

        case HiveParser.TOK_REVOKE:                                            

        case HiveParser.TOK_GRANT_ROLE:                                        

        case HiveParser.TOK_REVOKE_ROLE:                                       

            String userName = null;                                            

            if (SessionState.get() != null   && SessionState.get().getAuthenticator() != null) {        

                userName = SessionState.get().getAuthenticator().getUserName();

            }                                                                  

            if (!admin.equalsIgnoreCase(userName)) {                           

                throw new SemanticException(userName   + " can't use ADMIN options, except " + admin + ".");  

            }                                                                  

            break;                                                             

        default:    break;                                                             

        }                                                                      

        return ast;                                                            

    }                                                                          

}  

接着将该java文件编译、打包后放入hive的lib目录下并在hive-client的hive-site.xml添加属性

<!-- 配置超级管理员,需要自定义控制类继承这个 AbstractSemanticAnalyzerHook-->  

<property>  

   <name>hive.semantic.analyzer.hook</name>  

   <value>com.sunlands.eagle.etl.AdminHive</value>  

</property>  

添加了配置文件以后,如果启动了Hive Server,必须关闭重启功能才能生效。至此,只有admin用户可以进行Grant/Revoke操作。

hive --service metastore & 重新启动元数据服务

hiveserver2 & 启动hiveserver2

权限控制具体用户

权限校验时是以提交SQL的用户身份进行的,而具体执行SQL时是以HiveServer2用户身份(可以简单理解为HiveServer2的进程启动用户)进行的,因此HiveServer2用户需要具有读取HDFS目录或文件的权限,根据应用场景不同,可能也需要写/执行权限。

SQL标准的授权自定义登录校验

HiveServer2提供了JDBC链接操作Hive的功能,非常实用,但如果在使用HiveServer2时候,不注意安全控制,将非常危险,因为任何人都可以作为超级用户来操作Hive及HDFS数据。比如:在配置HiveServer2的时候,hive.server2.authentication=NONE,表示没有用户认证。HiveServer2的安全策略有三种方案:

1)LDAP Authentication using OpenLDAP

2)Setting up Authentication with Pluggable Access Modules

3)Configuring Custom Authentic

我选择第三种自定义登录校验,配置如下

<property>

<name>hive.server2.authentication</name>

<value>CUSTOM</value>

<description>

Expects one of [nosasl, none, ldap, kerberos, pam, custom].

Client authentication types.

NONE: no authentication check

LDAP: LDAP/AD based authentication

KERBEROS: Kerberos/GSSAPI authentication

CUSTOM: Custom authentication provider

(Use with property hive.server2.custom.authentication.class)

PAM: Pluggable authentication module

NOSASL: Raw transport

</description>

</property>

package com.sunlands.eagle.etl;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.conf.Configurable;

import org.apache.hadoop.conf.Configuration;

import org.apache.hive.service.auth.PasswdAuthenticationProvider;

import javax.security.sasl.AuthenticationException;

public class CustomHiveServer2Auth implements PasswdAuthenticationProvider,Configurable {

private static final Log LOG= LogFactory.getLog(CustomHiveServer2Auth.class);

private Configuration conf=null;

private static final String HIVE_JDBC_PASSWD_AUTH_PREFIX="hive.jdbc_passwd.auth.%s";

@Override

public void Authenticate(String username, String password) throws AuthenticationException {

LOG.info("user: "+username+" try login.");

String passwdMD5 = getConf().get(String.format(HIVE_JDBC_PASSWD_AUTH_PREFIX, username));

if(passwdMD5==null){

String message = "user's ACL configration is not found. user:"+username;

LOG.info(message);

throw new AuthenticationException(message);

}

String passMd5 = new MD5Utils().md5(password);

if(passwdMD5.equals(passMd5)) {

LOG.info("user "+username+" login system successfully.");

} else {

throw new AuthenticationException("user [" + username + "] auth check fail .. ");

}

}

@Override

public Configuration getConf() {

if(conf==null){

this.conf=new Configuration();

}

return conf;

}

@Override

public void setConf(Configuration arg0) {

this.conf=arg0;

}

}

package com.sunlands.eagle.etl;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

public class MD5Utils {

private MessageDigest digest;

private char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

public MD5Utils() {

try {

digest = MessageDigest.getInstance("MD5");

} catch (NoSuchAlgorithmException e) {

throw new RuntimeException(e);

}

}

public String md5(String str) {//MD5加密

byte[] btInput = str.getBytes();

digest.reset();

digest.update(btInput);

byte[] md = digest.digest();

int j = md.length;// 把密文转换成十六进制的字符串形式

char strChar[] = new char[j * 2];

int k = 0;

for (int i = 0; i < j; i++) {

byte byte0 = md[i];

strChar[k++] = hexDigits[byte0 >>> 4 & 0xf];

strChar[k++] = hexDigits[byte0 & 0xf];

}

return new String(strChar);

}

接着将该java文件编译、打包后放入hive的lib目录下并在hive-site.xml添加属性

<!-- 配置自定义校验类-->

<property>

<name>hive.server2.custom.authentication.class</name>

<value>com.sunlands.eagle.etl.CustomHiveServer2Auth</value>

</property>

多个用户可以添加多个property,里面配置的即用户名密码了。

<property>

<name>hive.jdbc_passwd.auth.muchaofeng</name>

<value>e55d5a05d5a10299de7866360609d71c</value>

</property>

<property>

<name>hive.jdbc_passwd.auth.eagle</name>

<value>354a9c5058d586c045ade937f91edea7</value>

</property>

<property>

<name>hive.jdbc_passwd.auth.root</name>

<value>f2fdea0fadfd0599a92d5bdc397ca633</value>

</property>

添加了配置文件以后,重新启动HiveServer2,必须关闭重启功能才能生效。

hiveserver2 & 启动hiveserver2

元数据查询

描述hive元数据库中比较重要的一些表的作用,mysql元数据库hive中的表:

表名

作用

BUCKETING_COLS

存储bucket字段信息,通过SD_ID与其他表关联

CDS

一个字段CD_ID,与SDS表关联

COLUMNS_V2

存储字段信息,通过CD_ID与其他表关联

DATABASE_PARAMS

DBS

存储hive的database信息

DELETEME1410257703262

FUNCS

FUNC_RU

GLOBAL_PRIVS

全局变量,与表无关

IDXS

INDEX_PARAMS

PARTITIONS

分区记录,SD_ID, TBL_ID关联

PARTITION_KEYS

存储分区字段,TBL_ID关联

PARTITION_KEY_VALS

分区的值,通过PART_ID关联。与PARTITION_KEYS共用同一个字段INTEGER_IDX来标示不同的分区字段。

PARTITION_PARAMS

存储某分区相关信息,包括文件数,文件大小,记录条数等。通过PART_ID关联

PART_COL_PRIVS

PART_COL_STATS

PART_PRIVS

ROLES

角色表,和GLOBAL_PRIVS配合,与表无关

SDS

存储输入输出format等信息,包括表的format和分区的format。关联字段CD_ID,SERDE_ID

SD_PARAMS

SEQUENCE_TABLE

存储sqeuence相关信息,与表无关

SERDES

存储序列化反序列化使用的类

SERDE_PARAMS

序列化反序列化相关信息,通过SERDE_ID关联

SKEWED_COL_NAMES

SKEWED_COL_VALUE_LOC_MAP

SKEWED_STRING_LIST

SKEWED_STRING_LIST_VALUES

SKEWED_VALUES

SORT_COLS

排序字段,通过SD_ID关联

TABLE_PARAMS

表相关信息,是否外部表,通过TBL_ID关联

TAB_COL_STATS

TBLS

存储表信息,关联字段DB_ID,SD_ID,

TBL_COL_PRIVS

TBL_PRIVS

表赋权限相关信息,通过TBL_ID关联

VERSION

版本

VERSION_copy

版本,通过VER_ID关联

登录mysql shell

mysql -u root -p

展示数据库

show databases;

使用数据库

use hive;

展示表

show tables;

查询角色与用户映射表

select * from ROLE_MAP;

Hive支持的权限控制如下表10-8所示。

操作

解释

ALL

所有权限

ALTER

允许修改元数据(modify metadata data of object)---表信息数据

UPDATE

允许修改物理数据(modify physical data of object)---实际数据

CREATE

允许进行Create操作

DROP

允许进行DROP操作

INDEX

允许建索引(目前还没有实现)

LOCK

当出现并发的使用允许用户进行LOCK和UNLOCK操作

SELECT

允许用户进行SELECT操作

SHOW_DATABASE

允许用户查看可用的数据库

hive 授权命令

角色的创建。语法:

CREATE ROLE ROLE_NAME

创建一个role_test1角色,命令如下

hive> create rolerole_test1;

OK

Time taken: 0.106 seconds

2)删除角色。语法:DROP ROLE ROLE_NAME

删除role_test1角色,命令如下:

hive> DROP ROLE role_test1;

2     角色的授权和撤销

角色的授权(GRANT)就是给角色授予创建表、查询表等操作,撤销(REVOKE)反之。语法如下:

GRANT ROLE role_name [,role_name] ... TO principal_specification [, principal_specification] ...

REVOKE ROLE role_name [,role_name] ... FROM principal_specification [, principal_specification]...

principal_specification :

USER user |GROUP group | ROLE role

看下面的实例。

1)把role_test1角色授权给jayliu用户,命令如下:

hive> grant role role_test1 to user jayliu;

OK

Time taken: 0.102 seconds

2)查看jayliu用户被授权的角色,命令如下:

hive> SHOW ROLE GRANTuser jayliu;

OK

role name:role_test1

role name:role_test1

Time taken: 7.913 seconds,Fetched: 2 row(s)

3)取消jayliu用户的role_test1角色,操作命令如下:

hive> revoke rolerole_test1 from user jayliu;

整理:

1.hive-site.xml 中配置的超级管理员账户 启动hive就会创建 不授予任何权限的情况下只能用来管理角色,权限。

2.权限可以赋值给用户也可以给角色,角色可以赋值给用户。

3.SQL标准的授权只包含增删改查,不包含组

4.SQL标准的授权默认不做登录校验,需要自定义实现

5.SQL标准的授权需要自定义实现超级权限

拓展:

(1) hive.security.authorization.manager to org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdConfOnlyAuthorizerFactory。这将确保由hive-cli创建的任何表或视图都具有为所有者授予的默认权限。

(2)将org.apache.hadoop.hive.ql.security.authorization

.MetaStoreAuthzAPIAuthorizerEmbedOnly添加到hive.security.metastore.authorization.manager。(它需要以逗号分隔的列表,因此您可以将其与StorageBasedAuthorization参数一起添加,如果您还要启用它)。此设置不允许在远程Metastore中调用任何授权api调用。HiveServer2可以

配置为使用嵌入式Metastore,这将允许它调用Metastore授权api。Hive cli和任何其他远程Metastore用户在尝试进行授权api调用时将被拒绝授权。这会将授权api限制为特权HiveServer2进程。

(3)beeline -u jdbc:hive2://192.168.0.80:10000/default -n eagle -p eagle@sunlandsTest

或者 [eagle@eagle80 ~]$ beeline

beeline> !connect jdbc:hive2://192.168.0.80:10000/default muchaofeng muchaofeng

猜你喜欢

转载自blog.csdn.net/qq_34394465/article/details/82589621