最新版本Kyuubi1.9.1 WebUI企业生产场景Basic LDAP安全认证实践案例总结

前言

之前文章已记录如何使用Kyuubi整合Spark与Flink计算引擎及KyuubiUI的使用方法,感兴趣的朋友请自行阅读。本文属于姊妹篇,继续记录WebUI在企业生产环境的场景下,如何开启WebUI的Basic LDAP安全认证,该特性也是1.9.1版本引入。欢迎关注微信公众号:大数据从业者!

Kyuubi LDAP认证

说明:如果没有或者不了解LDAP,参考下一章节的LDAP入门实践!

至于Kyuubi源码编译和安装部署,之前文章已经详细记录,本文不再重复赘述。根据本人的实践验证,Kyuubi WebUI开启Basic LDAP安全认证,需要修改kyuubi-default.conf,相关内容如下:

代码语言:javascript
复制
[root@felixzh apache-kyuubi-1.9.1-bin]# vim conf/kyuubi-defaults.conf
kyuubi.authentication LDAP
kyuubi.authentication.ldap.url ldap://felixzh2:389/
kyuubi.authentication.ldap.baseDN ou=People,dc=felixzh,dc=com
kyuubi.server.administrators felixzhUser

参数说明:

代码语言:javascript
复制
kyuubi.authentication支持多种认证,以逗号分割即可。比如同时开启KERBEROS和LDAP,可以配置为kyuubi.authentication为KERBEROS,LDAP。
kyuubi.authentication.ldap.url为你的LDAP服务地址端口信息。
kyuubi.authentication.ldap.baseDN为你的LDAP的全局唯一DN(distinguished name)。
kyuubi.server.administrators为管理员用户,只有管理员拥有WebUI所有操作权限。

实践验证

启动Kyuubi服务,日志会看到启用Basic认证添加相应BasicAuthenticationHandler的信息:

登录地址http://felixzh:10099,点击操作会提示输入用户名、密码:

注意:上述登录用户一定要归属于kyuubi.authentication.ldap.baseDN所配置的DN范围内。如果响应提示403 Forbidden,Error validating LDAP user,详细如下:

原因就是:baseDN配置的不对或者上述登录用户与密码不对。可以remote debug相应源码排查:

代码语言:javascript
复制
kyuubi\kyuubi-common\src\main\scala\org\apache\kyuubi\service\authentication\ldap\LdapSearchFactory.scala

登录成功,就可以执行SQL、查看Management相关目录,如下:

当然,使用kyuubi beeline也需要设置用户名和密码,如下:

代码语言:javascript
复制
./beeline -u 'jdbc:hive2://felixzh:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi1.9.1' -n felixzhUser -p admin@123

至此,Kyuubi WebUI Basic LDAP安全认证实践记录完成。至于更精细的库、表、列权限管理可以基于Ranger和Kyuubi插件kyuubi-spark-authz配合完成。

LDAP入门实践(可选)

OpenLDAP软件是LDAP协议的开源实现,具体包括lloadd(负载均衡进程)、slapd(服务端进程)、libraries(工具和样例)。

顾名思义,LDAP是一种轻量级协议,支持TCP/IP、用于访问目录服务。目录服务是一种用于存储、组织和检索信息的服务。LDAP中信息以树状结构组织,其中的基本数据单元就是条目;条目通常由一组属性(Attributes)组成,并且具有全局唯一DN(distinguished name)唯一标识。DN由RDN(Relative Distinguished Name)构成,RDN是条目的最后一级。比如表达式uid=felixzh,cn=online,ou=market,dc=example,dc=com就是一个dn,相当于数据库中的主键(primary key)。而属性由类型(type)和一个或者多个值(value)组成,相当于关系数据库中字段的概念。基于互联网域名的命名方法越来越流行,因为它允许使用DNS定位目录服务。下图展示一个使用基于域命名的LDAP目录树示例。

OpenLDAP使用嵌入式KV存储(如LMDB)而不使用关系数据库(RDBMS)。数据模型非常不同,用关系数据库表示目录数据需要将数据拆分为多个表,需要选择合适的键,性能会受到影响。LDAP最常见场景就是单点登录,很多开源软件都集成支持LDAP,比如Jenkins,GitLab、Jumpserver,Grafana、Kyuubi、Presto等等。

安装配置

代码语言:javascript
复制
[root@felixzh2 ~]# yum install -y openldap compat-openldap openldap-clients openldap-servers openldap-servers-sql openldap-devel migrationtools

其中,migrationtools可以同步Linux用户/用户组到LDAP。

通过slaptest校验配置:

代码语言:javascript
复制
[root@felixzh2 openldap]# slaptest

如上图所示,出于性能考虑建议配置DB_CONFIG文件,如下:

代码语言:javascript
复制
[root@felixzh2 openldap]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@felixzh2 openldap]# chown -R ldap:ldap /var/lib/ldap/

启动ldap

代码语言:javascript
复制
[root@felixzh2 openldap]# systemctl start slapd.service
[root@felixzh2 openldap]# systemctl status slapd.service

导入基础Schema

代码语言:javascript
复制
[root@felixzh2 openldap]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
[root@felixzh2 openldap]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
[root@felixzh2 openldap]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

生成密码

slappasswd是 OpenLDAP 提供命令行工具,用于生成LDAP加密密码。

代码语言:javascript
复制
[root@felixzh2 openldap]# slappasswd -s felixzh
{SSHA}bkNEreQG06lV6VBBPfCybhxImmBq3S0U

配置修改

不要直接修改LDAP配置文件,而采用自带ldapmodify工具修改:

代码语言:javascript
复制
ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/openldap/changes.ldif

上述changes.ldif就是想修改的管理配置,如baseDN、管理员、密码:

代码语言:javascript
复制
[root@felixzh2 openldap]# vim /etc/openldap/changes.ldif
dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcSuffix
olcSuffix:dc=felixzh,dc=com

dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcRootDN
olcRootDN:cn=Manager,dc=felixzh,dc=com

dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcRootPW
olcRootPW:{SSHA}bkNEreQG06lV6VBBPfCybhxImmBq3S0U

dn:cn=config
changetype:modify
replace:olcLogLevel
olcLogLevel:-1

dn:olcDatabase={1}monitor,cn=config
changetype:modify
replace:olcAccess
olcAccess:{0} to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=Manager,dc=felixzh,dc=com" read by * none

而实际场景通常需要以不同的OU区分实际的组织部门,如下:

代码语言:javascript
复制
[root@felixzh2 openldap]# vim  /etc/openldap/base.ldif
dn:dc=felixzh,dc=com
dc:felixzh
objectClass:top
objectClass:domain

dn:ou=People,dc=felixzh,dc=com
ou:People
objectClass:top
objectClass:organizationalUnit

dn:ou=Group,dc=felixzh,dc=com
ou:Group
objectClass:top
objectClass:organizationalUnit

通过ldapadd添加上述entry到ldap:

代码语言:javascript
复制
[root@felixzh2 openldap]# ldapadd -x -W -D cn=Manager,dc=felixzh,dc=com -f /etc/openldap/base.ldif

迁移linux账号为LDAP账号

OpenLDAP默认没有普通用户,为方便测试,新建linux用户和用户组:

代码语言:javascript
复制
[root@felixzh2 openldap]# groupadd felixzhUser
[root@felixzh2 openldap]# useradd -g felixzhUser felixzhUser
[root@felixzh2 openldap]# echo 'admin@123' | passwd --stdin felixzhUser
Changing password for user felixzhUser.
passwd: all authentication tokens updated successfully

使用migrationtools工具集中的migrate_passwd.pl将felixzhUser用户信息转换成users.ldif

代码语言:javascript
复制
[root@felixzh2 openldap]# cd /usr/share/migrationtools/
[root@felixzh2 migrationtools]# grep ":10[0-9][0-9]" /etc/passwd |grep felixzhUser > passwd
[root@felixzh2 migrationtools]# export LDAP_BASEDN=dc=felixzh,dc=com
[root@felixzh2 migrationtools]# export LDAP_DEFAULT_MAIL_DOMAIN=felixzh.com
[root@felixzh2 migrationtools]# ./migrate_passwd.pl passwd users.ldif

然后通过ldapadd将上述users.ldif添加到ldap:

代码语言:javascript
复制
[root@felixzh2 migrationtools]# ldapadd -x -w felixzh -D cn=Manager,dc=felixzh,dc=com -f users.ldif

验证效果

可以通过ldapsearch查看,如下:

代码语言:javascript
复制
[root@felixzh2 migrationtools]# ldapsearch -x cn=felixzhUser -b dc=felixzh,dc=com

也可以通过界面化工具查看,更为直观:

为了方便用户验证,写个简单Java程序测试,代码地址:

代码语言:javascript
复制
https://github.com/felixzh2020/felixzh-learning-java

管理员登录验证

普通用户登录验证