文章目录
前言
我的上一篇文章探讨了用户及库表权限,文章最后也抛出一个安全隐患,即用beeline访问hiveserver2时仍然出现任意用户可以随意操作hive集群的情况。
本文目标是:用beeline访问可以进行身份认证,并且登录的用户有权限认证。以下是正文。
一、提出问题:beeline登录后没有认证
官网解释:HiveServer2(HS2)是一个服务端接口,使远程客户端可以执行对Hive的查询并返回结果。目前基于Thrift RPC的实现是HiveServer的改进版本,并支持多客户端并发和身份验证。
据官网解释,beeline连接hiveserver2是有身份验证的,我在上一篇文章设置了用户权限后,用beeline以下命令却能访问任意库表,这就引出了对hiveServer2身份认证的思考。
beeline -u jdbc:hive2://192.168.0.25:10000/default -n cln
二、hiveServer2的身份认证
HiveServer2身份认证对应的hive属性为hive.server2.authentication,该属性有6个参数,分别是:
NONE: 不进行身份验证检查-普通的SASL传输。任何登录者都拥有超级权限,可以对hive进行任意操作。 LDAP: 基于LDAP/AD身份认证。 KERBEROS: Kerberos/GSSAPI 认证。 CUSTOM: 自定义身份验证提供程序(与hive.server2.custom.authentication.class一起使用) PAM:?可插拔认证模块。
NOSASL: ?原始传输。需要任意一个用户名,不需要密码,不填写或者填写错误用户名会导致报错
1.解决方案1:自定义hiveServer2
package com.costome.hs2.auth;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.security.sasl.AuthenticationException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
/**
* @Description:
* @Date: 2021/7/21 18:00
* @Auther: changlina
*/
public class CustomHiveServer2Auth implements PasswdAuthenticationProvider {
public static void main(String[] args) {
String md5 = new MD5().md5("waihui2021");//dcddb75469b4b4875094e14561e573d8
System.out.println(md5);
}
public void Authenticate(String user, String password) throws AuthenticationException {
boolean ok = false;
String passMd5 = new MD5().md5(password);
HiveConf hiveConf = new HiveConf();
Configuration conf = new Configuration(hiveConf);
String filePath = conf.get("hive.server2.custom.authentication.file");
System.out.println("hive.server2.custom.authentication.file [" + filePath + "] ..");
File file = new File(filePath);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempString = null;
while ((tempString = reader.readLine()) != null) {
String[] datas = tempString.split(",", -1);
if(datas.length != 2) {
continue;
}
//ok
if(datas[0].equals(user) && datas[1].equals(passMd5)) {
ok = true;
break;
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
throw new AuthenticationException("read auth config file error, [" + filePath + "] ..", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {}
}
}
if(ok) {
System.out.println("user [" + user + "] auth check ok .. ");
} else {
System.out.println("user [" + user + "] auth check fail .. ");
throw new AuthenticationException("user [" + user + "] auth check fail .. ");
}
}
//MD5加密
static class MD5 {
private MessageDigest digest;
private char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
public MD5() {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public String md5(String str) {
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);
}
}
}
pom.xml?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.costome.hs2</groupId>
<artifactId>auth</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-common</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-annotations</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-auth</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-client</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-hdfs</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<version>2.7.3</version>
</dependency>
<!--<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-common</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-annotations</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-auth</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-client</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-hdfs</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-client</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<version>2.7.6</version>
</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!--<archive>-->
<!--<manifest>-->
<!--<mainClass>-->
<!--</mainClass>-->
<!--</manifest>-->
<!--</archive>-->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
1. 将上面的程序打包成HiveServer2Auth.jar,放到$HIVE_HOME/lib下, 2.在hive-site.xml中设置以下参数: <property> <name>hive.server2.authentication</name> <value>CUSTOM</value> </property> <property> <name>hive.server2.custom.authentication.class</name> <value>com.costome.hs2.auth.CustomHiveServer2Auth</value> </property> <property> <name>hive.server2.custom.authentication.file</name> <value>/export/hive/conf/hive.server2.users.conf</value> </property> 3.在件/export/hive/conf/新建文件hive.server2.users.conf,里面内容如下:
changlina3,dcddb75469b4b4875094e14561e573d8 admin,dcddb75469b4b4875094e14561e573d8 4.重启hiveserver2
以下为测试:
[hdfs@v0106-c0a8003a lib]$ beeline
beeline> !connect jdbc:hive2://192.168.0.25:10000/default Connecting to jdbc:hive2://192.168.0.25:10000/default Enter username for jdbc:hive2://192.168.0.25:10000/default: changlina3 Enter password for jdbc:hive2://192.168.0.25:10000/default: *****
0: jdbc:hive2://192.168.0.25:10000/default> select current_user(); +-------+--+ | ?_c0 ?| +-------+--+ | hdfs ?| +-------+--+
发现仍然是hdfs用户
2.解决方案2:doAs配置
<property> ? <name>hive.server2.enable.doAs</name> ? <value>true</value>? </property>
?重启hiveserver2
[hdfs@v0106-c0a8003a lib]$ beeline
Beeline version 1.2.1.spark2 by Apache Hive
beeline> !connect jdbc:hive2://192.168.0.25:10000/default
Connecting to jdbc:hive2://192.168.0.25:10000/default
Enter username for jdbc:hive2://192.168.0.25:10000/default: changlina3
Enter password for jdbc:hive2://192.168.0.25:10000/default: *****
2021-07-23 18:46:43 INFO Utils:310 - Supplied authorities: 192.168.0.25:10000
2021-07-23 18:46:43 INFO Utils:397 - Resolved authority: 192.168.0.25:10000
2021-07-23 18:46:43 INFO HiveConnection:203 - Will try to open client transport with JDBC Uri: jdbc:hive2://192.168.0.25:10000/default
Connected to: Apache Hive (version 2.3.2)
Driver: Hive JDBC (version 1.2.1.spark2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://192.168.0.25:10000/default> select current_user();
+-------------+--+
| _c0 |
+-------------+--+
| changlina3 |
+-------------+--+
1 row selected (1.868 seconds)
思考:beeline -u"jdbc:hive2://192.168.0.25:10000/default;hive.server2.proxy.user=changlina3"
hive.server2.proxy.user也可以通过代理访问有权限的表
总结
要解决问题,目前我的方法是2.1和2.2的方案一起做。目标就是:用户必须登录才可以访问hive,而且登录的用户只能访问有权限的库表。
|