关键字:hiveserver2、用户安全
HiveServer2提供了JDBC链接操作Hive的功能,非常实用,但如果在使用HiveServer2时候,不注意安全控制,将非常危险,因为任何人都可以作为超级用户来操作Hive及HDFS数据。
比如:在配置HiveServer2的时候,hive.server2.authentication=NONE,表示没有用户认证。
使用beeline,模拟成超级用户hadoop,成功连接到HiveServer2.
创建数据库lxw1234;
0: jdbc:hive2://localhost:10000> create database lxw1234;
No rows affected (0.157 seconds)
0: jdbc:hive2://localhost:10000>
HDFS上也是以超级用户hadoop创建的目录。
再执行drop database,同样没问题。
0: jdbc:hive2://localhost:10000> drop database lxw1234;
No rows affected (0.142 seconds)
0: jdbc:hive2://localhost:10000>
如果是以普通用户链接HiveServer2,执行创建数据库,则会报权限错误,因为普通用户没有在Hive根目录的写权限:
因此,如果使用HiverServer2来提供给用户来链接Hive,必须启用安全认证,也就是hive.server2.authentication的配置。
目前HiveServer2支持多种用户安全认证方式:NONE,NOSASL, KERBEROS, LDAP, PAM ,CUSTOM等等。
本文介绍使用自定义的用户认证方式,即CUSTOM;
如果将hive.server2.authentication设置成CUSTOM,则需要设置
hive.server2.custom.authentication.class来指定用于权限认证的类,这个类需要实现
org.apache.hive.service.auth.PasswdAuthenticationProvider接口。
我们将使用HiveServer2的用户名和密码保存起来,其中,密码以32位小写md5加密来保存,这个数据即可以保存在Hive元数据库中,也可以保存在一个配置文件中。为了方便起见,这里使用配置文件来保存。
首先需要编写用户权限验证的类:
package com.lxw1234.hive.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; public class CustomHiveServer2Auth implements PasswdAuthenticationProvider { @Override public void Authenticate(String username, 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(username) && 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 [" + username + "] auth check ok .. "); } else { System.out.println("user [" + username + "] auth check fail .. "); throw new AuthenticationException("user [" + username + "] auth check fail .. "); } } //MD5加密 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); } } }
将上面的程序打包成HiveServer2Auth.jar,放到$HIVE_HOME/lib下,
在hive-site.xml中设置以下参数:
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value>
</property>
<property>
<name>hive.server2.custom.authentication.class</name>
<value>com.lxw1234.hive.auth.CustomHiveServer2Auth</value>
</property>
<property>
<name>hive.server2.custom.authentication.file</name>
<value>/usr/local/apache-hive-0.13.1-bin/conf/hive.server2.users.conf</value>
</property>
在$HIVE_HOME/conf下新建文件hive.server2.users.conf,里面写入内容:
[root@dev conf]# cat hive.server2.users.conf
lxw1234,48d9a656690e1b1bf5ddee4c12d1bbd7
user,5f4dcc3b5aa765d61d8327deb882cf99
其中,48d9a656690e1b1bf5ddee4c12d1bbd7为lxw1234_password的md5加密,
5f4dcc3b5aa765d61d8327deb882cf99为password的md5加密。
接下来,重新启动HiveServer2,使用beeline连接:
再次使用hadoop用户连接,输入空密码或者不正确的密码,将不会再链接到HiveServer。
HiveServer2的日志中打印出了认证失败的消息。
再试试使用用户lxw1234密码lxw1234_password连接:
日志中打印出user [lxw1234] auth check ok ..
同样,已经配置过的user用户密码password也可以正常连接:
使用Java JDBC连接HiveServer2,密码错误将不能正常连接:
密码正确时才可以正常查询:
这种方式做的HiveServer2用户认证,可以动态的增加、修改和删除用户及密码,只需要修改hive.server2.custom.authentication.file 配置文件即可。
当然,用户名和密码也可以保存在Hive元数据库,每次认证时候查询即可。
更多Hive相关的文章可查看 一起学Hive系列
您可以关注 lxw的大数据田地 ,或者 加入邮件列表 ,随时接收博客更新的通知邮件。
如果觉得本博客对您有帮助,请 赞助作者 。