有一个问题一直困扰LZ,使用beeline客户端连接HiveSever的时候,登录的username和password到底有什么用处?工作中都是直接两个回车键就跳过了,LZ在想是否能利用这个来做Hive的权限管理。
** 1. 登陆用户 **
LZ使用hadoop用户启动HDFS,使用hive用户启动hiveserver2和metastore,使用superman用户登录beeline客户端。启动hive前,进行以下操作:
1 2 3 4 |
hdfs dfs -mkdir -p /user/hive hdfs dfs -chown -R hive:hive /user/hive hdfs dfs -chmod 777 /tmp |
hive-site.xml
1 2 3 4 5 |
<property> <name>hive.server2.enable.doAs</name> <value>true</value> </property> |
当hive.server2.enable.doAs = false时,不管使用哪个username登录,hive都是用hive用户的身份向yarn提交任务。当hive.server2.enable.doAs = true时,hive使用username用户的身份向yarn提交任务。使用后者,还要添加下面的配置:
core-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<property> <name>hadoop.proxyuser.hive.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hive.groups</name> <value>hive</value> </property> <!-- <property> <name>hadoop.proxyuser.hive.users</name> <value></value> </property> --> |
HDFS服务允许hive用户代理hadoop.proxyuser.hive.hosts主机上的,hadoop.proxyuser.hive.groups组下的,以及hadoop.proxyuser.hive.users用户。操作时有代理用户的权限,没有hive用户的权限。上面配置的含义:任意主机的beeline都可以连接本机的hive服务,登陆用的username要添加到本机的hive用户组里面才可以登陆。LZ公司hive都配置的是*(hive.server2.enable.doAs = false),所以直接两个回车就能登陆。用上面的配置的话,就会报错:
1 2 |
Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: hive is not allowed to impersonate anonymous (state=08S01,code=0) |
不输入用户名,默认用户是anonymous。因为anonymous没有加入到hive用户组中,所以异常为hive用户无法代理anonymous用户。LZ把superman用户添加到hive用户组中,就可以使用superman用户登陆了(即使你当前的Linux用户不是superman,也可以用其登陆),现在还不需要使用密码。但是还不能创建数据库,因为superman用户在/user/hive/warehouse下是没有写权限的(drwxr-xr-x hive hive)。LZ的解决方案是:
1 2 |
hdfs dfs -chmod g+w /user/hive/warehouse |
很多人都是直接给777权限,LZ觉得那样很不安全。现在superman就可以建库建表了,HDFS上数据库目录的用户也是superman了。但是数据库目录的权限继承了warehouse的目录权限(drwxrwxr-x),因为hive的每个用户都添加到了hive的用户组中,所以数据库目录对任意用户都是有写权限的,这样存在安全隐患。可以在hive-site.xml里面添加下面的配置:
1 2 3 4 5 |
<property> <name>hive.warehouse.subdir.inherit.perms</name> <value>false</value> </property> |
这样数据库目录就不会继承warehouse的目录权限,而是使用HDFS配置的dfs.umask值(默认0002)。
** 2. 登陆密码 **
登陆不需要密码,存在很大的风险。比如有人知道了用户名,就可以删除数据。LZ尝试给登陆用户添加密码。hive.server2.authentication –身份验证模式,默认为 NONE。选项为 NONE(使用普通 SASL),NOSASL,KERBEROS,LDAP,PAM 和 CUSTOM。第三方验证太麻烦,LZ使用自定义CUSTOM模式来演示。
使用CUSTOM模式要自己定义验证类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class CustomPasswdAuthentication implements PasswdAuthenticationProvider, Configurable { private static final String HIVE_BEELINE_USERS_PREFIX = "hive.beeline.users.%s"; private Configuration conf = null; public void Authenticate(String username, String password) throws AuthenticationException { String passwordMD5 = getConf().get(String.format(HIVE_BEELINE_USERS_PREFIX, username)); if (passwordMD5 == null) { throw new AuthenticationException("user's ACL configration is not found. user:" + username); } if (!passwordMD5.equals(DigestUtils.md5Hex(password))) { throw new AuthenticationException("username and password is mismatch. user:" + username); } } public void setConf(Configuration conf) { this.conf = conf; } public Configuration getConf() { if (conf == null) { this.conf = new Configuration(); } return conf; } } |
验证不通过时候抛出异常即可。然后打个包丢到hive的lib目录下面,并且添加配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<property> <name>hive.server2.authentication</name> <value>CUSTOM</value> </property> <property> <name>hive.server2.custom.authentication.class</name> <value>com.ee.authentications.CustomPasswdAuthentication</value> </property> <property> <name>hive.beeline.users.superman</name> <value>84d961568a65073a3bcf0eb216b2a576</value> </property> |
密码LZ用md5进行了加密,在登陆的时候使用加密前的明文密码登陆,这样安全些。
** 3. 权限管理 **
99 Replies to “Hive的权限管理”