公司用的cdh版本为5.14,sentry集成的步骤很简单,参照官方文档就可以完成了:
https://www.cloudera.com/documentation/enterprise/5-14-x/topics/sentry.html
本文主要写一些openldap的搭建和phpldap的使用,还有ldap和(hive,impala,hue)的整合。
ldap的具体概念可以参照这篇文章
LDAP概念和原理介绍
一.安装OpenLDAP
yum install openldap openldap-clients openldap-servers
安装完直接启动
```
service slapd start
```
设置管理员密码 ```
slappasswd -h {SSHA}
```
然后会让你输入一个明文密码,返回给你一个加密的密码,记住这个返回的密码
使用ldapsearch命令查询管理员的dn:
ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config "olcRootDN=cn=Manager,dc=my-domain,dc=com" dn olcRootDN olcRootPW
这里返回的dn是olcDatabase={2}hdb,cn=config,密码等信息也都一并返回。这里有用的是dn和密码的加密方式,比如这里是SSHA,dn是后面修改的Entry DN,而知道密码的加密方式就可以使用该加密方式生成新密码。
使用ldapmodify修改条目
vim chrootpw.ldif
#这是第1步获取的管理员dn
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
#你想要改成的域名的后缀
olcSuffix: dc=xinniu,dc=com
#olcSuffix这几行一定要加,否则修改之后会出错,后面重启openldap都会失败
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
#你想要改成的域名
olcRootDN: cn=admin,dc=xinniu,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootPW
#这里就是刚才保存下来的那个加密后的密码
olcRootPW: {SSHA}uYnICxla0NrUC5b/ha4i1JeOTCoUchV+
如图:
使用下面的命令来修改管理员条目:
ldapmodify -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif
如果出现:
modifying entry "olcDatabase={2}bdb,cn=config"
重启服务使修改生效
/etc/init.d/slapd restart
导入基本数据结构
我们需要向 LDAP 中导入一些基本的 Schema。这些 Schema 文件位于 /etc/openldap/schema/ 目录中,schema控制着条目拥有哪些对象类和属性
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/collective.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/corba.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/core.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/duaconf.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/dyngroup.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/java.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/misc.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/openldap.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/pmi.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f /etc/openldap/schema/ppolicy.ldif
到此就设定好了管理员的密码。可以用客户端去管理openldap了
打算使用phpldapadmin来管理openldap,这个工具使用的人较多,网上文档多,出现问题容易解决。
二.安装phpldapadmin(ldap管理工具)
首先安装Apache和PHP:
yum -y install httpd php php-ldap php-gd php-mbstring php-pear php-bcmath php-xml
然后安装phpldapadmin:
yum -y install phpldapadmin
httpd与phpldapadmin进行集成:
修改配置文件:
[root@localhost ~]# vim /etc/phpldapadmin/config.php
#397行取消注释,398行添加注释
$servers->setValue('login','attr','dn');
// $servers->setValue('login','attr','uid');
这里需要修改,如果不修改,phpldapadmin会去用uid去搜索条目,不会用dn去搜索,导致报密码错误。
[root@localhost ~]# phpldapadmin的ip过滤规则默认是拒绝所有ip访问,先去修改一下规则,我们才可以访问
vim /etc/httpd/conf.d/phpldapadmin.conf
##这是Apache2.2和以前的修改方法
// 修改配置
<IfModule mod_authz_core.c>
</IfModule>
把下面的Deny from all 改为Allow from all
##这是apache2.4和以后的修改方法
#允许172.16.10.16访问
Require ip 172.16.10.16
#允许172.16这个网段访问
Require ip 172.16.0.0/16
#允许所有ip访问
Require all granted
我们可以根据自己需要修改来
修改完之后启动:
service httpd restart
界面:
登陆
用户名,默认是 cn=Manager,dc=my-domain,dc=com(这个也可以改的,仿照修改密码的步骤)
密码就输入刚开始设置的密码
登陆进去后,我的管理界面报这个信息:
This base cannot be created with PLA
显示结果如下:
经过查询,原因是根结点需要初始化后才能使用,最终处理如下:
1、创建一个initroot.ldif文件,为创建初始化根节点做准备工作,如下所示:
dn: dc=xinniu,dc=com
#域名的后缀
o: ldap
objectclass: dcObject
objectclass: organization
2、执行ldapadd -f initroot.ldif -x -D cn=admin,dc=xinniu,dc=com -W 输入之前配置OpenLDAP的密码后,即可完成创建LDAP根节点,如下图所示:
完成以上操作后,再回到phpldapadmin页面,可以看到,已经正常出现了根节点,并可以创建相关OU、Group、Account等对象,如下图所示:
三.整合ldap和hive,impala,hue
先用phpldapadmin在ldap创建一个用户去测试:
首先创建一个ou,叫users
然后再在users下创建一个用户:jiandan
在创建新条目时,选择Generic User Account,创建好以后会出现cn=jiandan这个条目。
然后点击cn=jiandan这个条目,点击更名,把cn=jiandan修改为uid=jiandan,因为hive后面会在ldap中默认去搜索uid,如果使用cn还需要额外去高级配置中配置一个自定义的属性。
1.首先整合hive:
在cdh里面修改一下配置:
这张图用的别人的,如果按我的配置,BaseDN则写:
ou=users,dc=my-domain,dc=com
然后用beeline进行测试
这样就是通过ldap的验证了,如果密码不正确则会:
后来生产上hive整合ldap的时候遇到一个问题,hue和impala都不会出现,当使用其他部门的LDAP而不是自建的LDAP时可能会出现。
那就是hive.server2.authentication.ldap.baseDN这个配置项,hive在ldap中验证用户时,会通过uid去匹配用户,如:uid=xiaohuang,ou=users,dc=my-domain,dc=com。问题是有时候ldap并不一定是我们部门自己搭建的,而是技术中心的运维那边搭建的,他们在LDAP创建用户条目时,并没有给条目一个uid的属性,而是建了一个CN的属性,如:cn=xiaohuang,ou=users,dc=my-domain,dc=com这种,我们使用了上面文档的配置,必然会搜不到,导致验证失败。
这个时候咋办?让他们帮我们重新建个我们想要的条目?他们肯定不鸟。。
然而我就这样放弃了么?不可能的,通过去官方文档查看,找到这篇文章
https://cwiki.apache.org/confluence/display/Hive/User+and+Group+Filter+Support+with+LDAP+Atn+Provider+in+HiveServer2#UserandGroupFilterSupportwithLDAPAtnProviderinHiveServer2-hive.server2.authentication.ldap.userDNPattern
看到有个属性,它也可以使hive和imapla,hue一样,通过通配符去设定,让hive去LDAP中查找指定的条目。
这个属性要在
hive-site.xml 的 Hive 服务高级配置代码段(安全阀)
中配置
<property><name>hive.server2.authentication.ldap.userDNPattern</name><value>cn=%s,ou=users,dc=my-domain,dc=com</value><final>true</final></property>
这样即可让hive在做账户验证的时候,去搜索CN开头的条目,而不是UID开头的条目
。巧妙地解决了这个问题。
2.然后整合impala:
修改配置,和hive类似:
不过要在高级代码段里面增加一个参数,因为我们的密码是明文传输,否则imapala启动不了。
重启impala后,我们来测试
发现已经ok了。
3.最后我们来整合hue
首先需要配置这些
这个配置好以后,我们就可以登陆hue了,我们看到登陆的界面已经多了个ldap
登陆已经可以了,不过登陆进去后会报一些错误:
[文件]
我们需要配置一些额外的参数从而让hue用户可以代理其他的用户
1.在ldap中创建hue用户
2.hue_safety_valve.ini 的 Hue 服务高级配置代码段(安全阀)中配这些
[beeswax]
close_queries=True
use_sasl=False
auth_username=hue
auth_password=xxxxxxx
[impala]
server_host=datanode1
server_interface=hiveserver2
server_port=21050
query_timeout_s=100
impersonation_enabled=True
auth_username=hue
auth_password=xxxxxxx
在hive和i mpala的core-site.xml 的 Hive 服务高级配置代码段(安全阀)中增加以下配置:
impala的Impala 命令行参数高级配置代码段(安全阀)中再加上
–authorized_proxy_user_config=hue=*
然后就不会报这个错误了。
以上就基本完成了ldap和hive impala hue的整合。
四.hadoop user -> group 映射关系集成ldap
1.原理
在sentry的使用中,我们发现,sentry的授权是基于角色的,而角色又是通过组来分配的,在实际hive/impala使用当中,我们使用一个用户,hive如何知道它有哪些权限呢?实际上是通过user -> group -> role这么一个映射关系来完成每一次权限的操作,group -> role的映射关系是通过sentry数据库管理:
sentry通过sentry_role,sentry_group,sentry_role_group_map这3个库管理了group和role的mapping关系。
而user-group的映射关系是如何实现的?
hive中有个相关选项,默认使用了hadoop的用户组信息,也就是说,hive中涉及到user->group这个映射关系是直接用的hdfs的,而hdfs的user->group这个映射信息来自于哪里?
打开hdfs的配置,我们发现:
有这么一个配置项,hdfs的group信息默认实际是调用的本地shell的group信息!
2.问题以及原因
细节明白以后,再说说实际的问题,如果我们使用默认的配置,那么hive和impala的时候,我们去连接hiveserver,或者impalad,如果本地没有相应的用户,那么sentry就没法获取到 user->group 的信息,那么就无法完成权限认证的整条链路,就会报错。
那么我们每次有新同事加入,就需要在每个相关节点上创建相应的用户,这样实际上不仅麻烦,而且很low(这是最主要的),即使你写批量脚本。
3.解决方案
那么我们可以通过ldap来存储这个user->group的映射关系,这样hdfs就不必再去本地找这个映射关系了。
我们先把当前系统上的用户和组导入到ldap,需要用到一个工具:migrationtools
3.1安装migrationtools
yum install -y migrationtools
.修改migrate_common.ph
vim /usr/share/migrationtools/migrate_common.ph
Default DNS domain
DEFAULT_MAIL_DOMAIN = "zpbigdata.com";
Default base
DEFAULT_BASE = "dc=zpbigdata,dc=com";
利用pl脚本将/etc/passwd 和/etc/group生成LDAP能读懂的文件格式
这里导入一个etl用户来测试
cat /etc/passwd | grep etl > /tmp/passwd
cat /etc/group | grep etl > /tmp/group
/usr/share/migrationtools/migrate_base.pl > /tmp/base.ldif
/usr/share/migrationtools/migrate_passwd.pl /tmp/passwd > /tmp/passwd.ldif
/usr/share/migrationtools/migrate_group.pl /tmp/group > /tmp/group.ldif
将文件导入到LDAP
ldapadd -x -D "cn=Manager,dc=zpbigdata,dc=com" -W -f /tmp/base.ldif
ldapadd -x -D "cn=Manager,dc=zpbigdata,dc=com" -W -f /tmp/passwd.ldif
ldapadd -x -D "cn=Manager,dc=zpbigdata,dc=com" -W -f /tmp/group.ldif
这样就把people和group信息导入了
3.2修改hdfs的配置
把hadoop.security.group.mapping的值改为org.apache.hadoop.security.LdapGroupsMapping
然后填写Ldap的相关参数:
大致就是这么多项配置需要填写,仅供参考,具体的值还是要参考你ldap中建立的group中和people中对象的具体属性
4.验证
配置完成后使用以下命令测试:
sudo -u hdfs hdfs groups xxx(username)
打印的group值如果和ldap中你配置的可以对应上,那么就证明完成了。
后续添加新的group和user,只需要在ldap中添加就好了。
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/192631.html