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、驱动、用户名、密码等属性值配置如下:
ps:需要把mysql的驱动包copy到目录
如果是第一次需要执行初始化命令:schematool -dbType mysql -initSchema
配置完成之后启动元数据服务,然后使用hive进入shell进行交互式查询。
Remote方式
客户端配置都在一个 hive-site.xml 中,属性值配置如下:
hive metastore 服务端启动命令:
hive --service metastore 启动元数据服务
三种部署方式区别总结:
授权模式概述
1、旧的默认Hive授权(传统模式)
Hive旧默认授权(在Hive 2.0.0之前是默认授权)是早期版本的Hive中可用的授权模式。但是,此模式没有完整的访问控制模型,因此未解决许多安全漏洞。例如,未定义为用户授予权限所需的权限,并且任何用户都可以授予自己对表或数据库的访问权限。
此模型类似于基于SQL标准的授权模式,因为它提供基于grant / revoke语句的访问控制。但是,访问控制策略与基于SQL标准的授权不同,并且它们不兼容。
2、 Metastore Server中基于存储的授权
通过在Metastore Server中启用基于存储的授权, 会控制元数据对象(如数据库,表和分区)上的元数据访问,它会检查您是否拥有文件系统上相应目录的权限。
Metastore Server中基于存储的授权
3、 HiveServer2中基于SQL标准的授权
尽管基于存储的授权可以在数据库,表和分区级别提供访问控制,但它无法控制更精细级别的授权,例如列和视图,因为文件系统提供的访问控制位于目录和文件级别。细粒度访问控制的先决条件是数据服务器,它只能提供用户需要访问的列和行。在文件系统访问的情况下,整个文件被提供给用户。HiveServer2满足这个条件,因为它有一个理解行和列的API(通过使用SQL),并且只能提供SQL查询所要求的列和行。
基于SQL标准的授权 (在Hive 0.13.0中引入) 可用于实现细粒度访问控制。它基于授权的SQL标准,并使用熟悉的grant / revoke语句来控制访问。需要通过HiveServer2配置启用它。
请注意,对于Hive命令行,禁用基于SQL标准的授权。这是因为在Hive中使用访问控制策略的Hive命令行无法进行安全访问控制,因为用户可以直接访问HDFS,因此他们可以轻松绕过基于SQL标准的授权检查,甚至完全禁用它。禁用此功能可避免给用户带来错误的安全感。
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).
SQL Standards Based Authorization in HiveServer2默认提供两种角色:public和admin,所有用户默认属于角色public,而授权则必须是具有角色admin的用户才可以完成(普通用户仅可以将自己获得的权限授权给其它用户),因此我们必须添加至少一个用户拥有角色admin
Comma separated list of users who are in admin role for bootstrapping.
More users can be added in ADMIN role later.
Setting this property to true will have HiveServer2 execute
Hive operations as the user making the calls to it.
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).
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.
hive client authenticator manager class name. The user defined authenticator should implement
interface org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider.
超级权限
此时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添加属性
添加了配置文件以后,如果启动了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
我选择第三种自定义登录校验,配置如下
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
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,里面配置的即用户名密码了。
添加了配置文件以后,重新启动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