【译】Clickhouse与LDAP集成(一)

简介: 【译】Clickhouse与LDAP集成(一)

ClickHouse上一般使用XML文件来定义配置,其中包括用户配置。users.xml文件或在/etc/clickhouse-server/users.d目录中的配置文件都可用于定义用户及其相关属性,例如profilenetwork restrictionquotapassword。这种方案在集群规模较小时比较有效,但是用来管理大规模集群却很费劲。


主要存在三个主要问题:首先每次必须添加、修改或删除用户时,管理员必须手动编辑这些配置文件;其次,将密码和哈希值直接存储在用户配置文件中存在安全隐患;第三,为用户分配和管理角色是非常繁琐的。


ClickHouse现在已经解决了以上三个问题。通过引入对RBAC的支持,ClickHouse允许使用SQL语句管理用户和角色,而无需修改配置文件。但是即使使用RBAC,您仍然需要与组织内的其他服务分别管理用户和角色,相互之间无法打通,且密码仍然存储在文件系统中。


自2020年中以来,Altinity一直在努力添加ClickHouse对轻型目录访问协议(也称为LDAP)的支持。LDAP集中存储用户、密码及其在组织中角色,从而使得管理用户和权限的功能集中到一个地方。我们很高兴地宣布,ClickHouse支持LDAP身份验证和用户目录的特性已被合入社区,目前运行稳定且通用。


我们已使用大多数Linux发行版中提供的常用OpenLDAP软件包对其进行了仔细的测试。


在这一系列博客文章中,我们将描述对LDAP集成的新支持如何帮助中大型组织将ClickHouse用户角色管理与其现有服务集成在一起。我们将介绍LDAP与Clickhouse的几种不同程度的集成,从使用LDAP验证ClickHouse用户,到通过外部用户目录完全集成LDAP并将选定的LDAP组映射到RBAC中的角色。




测试环境


我们使用docker-compose集群来展示LDAP如何与ClickHouse集成。


您可以在https://gitlab.com/altinity-public/blogs/ldap-integration-with-clickhouse上找到docker-compose环境,该环境中使用了yandex/clickhouse-server:21.1.2.15镜像

要使用该环境,需要在系统上安装gitdockerdocker-compose。然后将包含测试环境的代码库克隆到本地。


git clone https://gitlab.com/altinity-public/blogs/ldap-integration-with-clickhouse.git


检查是否可以启动docker-compose集群。


cd  ldap-integration-with-clickhouse  
cd docker-compose/  
docker-compose up -d


Creating network "docker-compose_default" with the default driver  
Creating docker-compose_openldap1_1 ... done  
Creating docker-compose_zookeeper_1 ... done  
Creating docker-compose_clickhouse1_1 ... done  
Creating docker-compose_clickhouse3_1 ... done  
Creating docker-compose_clickhouse2_1 ... done  
Creating phpldapadmin                 ... done  
Creating docker-compose_all_services_ready_1 ... done


如果启动成功会看到上面的日志,表明openldap1zookeeperclickhouse1clickhouse2clickhouse3phpldapadmin这些服务已经正常运行。我们还可检查所有服务是否健康。


请注意,您必须执行docker-compose目录下的所有docker-compose命令


docker-compose ps


Name                              Command                  State                   Ports              
-------------------------------------------------------------------------------------------------------------------  
docker-compose_all_services_ready_1   /hello                           Exit 0                                        
docker-compose_clickhouse1_1          bash -c clickhouse server  ...   Up (healthy)   8123/tcp, 9000/tcp, 9009/tcp   
docker-compose_clickhouse2_1          bash -c clickhouse server  ...   Up (healthy)   8123/tcp, 9000/tcp, 9009/tcp   
docker-compose_clickhouse3_1          bash -c clickhouse server  ...   Up (healthy)   8123/tcp, 9000/tcp, 9009/tcp   
docker-compose_openldap1_1            /container/tool/run --copy ...   Up (healthy)   389/tcp, 636/tcp               
docker-compose_zookeeper_1            /docker-entrypoint.sh zkSe ...   Up (healthy)   2181/tcp, 2888/tcp, 3888/tcp   
phpldapadmin                          /container/tool/run              Up (healthy)   443/tcp, 0.0.0.0:8080->80/tcp




健全性检查


在继续之前我们做一些必要的健全性检查。首先,确保我们的OpenLDAP Server已启动并正在运行。我们可以执行搜索操作以查看在LDAP Server上定义好的用户


再次注意,您必须执行docker-compose目录下的所有docker-compose命令。

docker-compose exec openldap1 bash -c 'ldapsearch -x -H ldap://localhost -b "ou=users,dc=company,dc=com" -D "cn=admin,dc=company,dc=com" -w admin'


# extended LDIF  
#  
# LDAPv3  
# base <ou=users,dc=company,dc=com> with scope subtree  
# filter: (objectclass=*)  
# requesting: ALL  
#  
# users, company.com  
dn: ou=users,dc=company,dc=com  
objectClass: organizationalUnit  
objectClass: top  
ou: users  
# ldapuser, users, company.com  
dn: cn=ldapuser,ou=users,dc=company,dc=com  
cn: ldapuser  
gidNumber: 501  
givenName: John  
homeDirectory: /home/users/ldapuser  
objectClass: inetOrgPerson  
objectClass: posixAccount  
objectClass: top  
sn: User  
uid: ldapuser  
uidNumber: 1002  
userPassword:: bGRhcHVzZXI=  
# search result  
search: 2  
result: 0 Success  
# numResponses: 3  
# numEntries: 2



可以看到,我们已经定义了一个用户:cn=ldapuser,ou=users,dc=company,dc=comldapsearch返回的数据中,ldapuser为用户名,密码设置为与用户名相同(仅用于测试)。


其次,确保ClickHouse服务能够正常执行查询。


docker-compose exec clickhouse1 bash -c 'clickhouse-client -q "SELECT version()"'  
docker-compose exec clickhouse2 bash -c 'clickhouse-client -q "SELECT version()"'  
docker-compose exec clickhouse3 bash -c 'clickhouse-client -q "SELECT version()"'




在ClickHouse中配置LDAP服务器


在将LDAP与ClickHouse进行集成之前,需要让ClickHouse知道哪里有可用的LDAP服务器以及如何连接它,Clickhouse甚至还可以添加多个LDAP Server的配置。为简单起见,我们将仅使用在docker-compose集群中的openldap1环境。接下来将配置文件添加到/etc/clickhouse-server/config.d目录中,以配置LDAP Server。


docker-compose exec clickhouse1 bash -c 'cat <<HEREDOC > /etc/clickhouse-server/config.d/ldap_servers.xml  
<?xml version="1.0" encoding="utf-8"?>  
<yandex>  
  <ldap_servers>  
    <!--LDAP servers b9f1f80c_6598_11eb_80c1_39d7fbdc1e26-->  
    <openldap1>  
      <host>openldap1</host>  
      <port>636</port>  
      <enable_tls>yes</enable_tls>  
      <auth_dn_prefix>cn=</auth_dn_prefix>  
      <auth_dn_suffix>,ou=users,dc=company,dc=com</auth_dn_suffix>  
      <tls_require_cert>never</tls_require_cert>  
    </openldap1>  
  </ldap_servers>  
</yandex>  
HEREDOC'


接着检查ldap_servers.xml中的配置是否已合并到预处理的config.xml文件中。


docker-compose exec clickhouse1 bash -c 'cat /var/lib/clickhouse/preprocessed_configs/config.xml | grep LDAP'


<!--LDAP servers b9f1f80c_6598_11eb_80c1_39d7fbdc1e26-->


可以看到唯一标识字符串已经在预处理的config.xml文件中,说明LDAP Server配置已被Clickhouse成功加载。




使用LDAP验证ClickHouse用户


ClickHouse与LDAP的第一级集成是允许使用LDAP Server对ClickHouse用户进行身份验证。这样我们就不必在Clickhouse中为用户明确指定密码,而是让ClickHouse请求LDAP Server进行用户身份验证。




在users.xml中定义经过LDAP Server验证的用户


我们可将对应的配置文件添加到/etc/clickhouse-server/users.d目录中以新建Clickhouse用户,而不需要在配置中为其指定密码,转而用LDAP Server配置代替之。


docker-compose exec clickhouse1 bash -c 'cat <<HEREDOC > /etc/clickhouse-server/users.d/ldapuser.xml  
<?xml version="1.0" encoding="utf-8"?>  
<yandex>  
  <users>  
    <!--LDAP users bb6f3d71_6598_11eb_80c1_39d7fbdc1e26-->  
    <ldapuser>  
      <ldap>  
        <server>openldap1</server>  
      </ldap>  
    </ldapuser>  
  </users>  
</yandex>  
HEREDOC'


确认新增用户配置已合并到预处理的users.xml中。


$ docker-compose exec clickhouse1 bash -c 'cat /var/lib/clickhouse/preprocessed_configs/users.xml | grep bb6f3d71_6598_11eb_80c1_39d7fbdc1e26'


<!--LDAP users bb6f3d71_6598_11eb_80c1_39d7fbdc1e26-->


现在我们使用ldapuser用户执行查询。


docker-compose exec clickhouse1 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT user()"'


ldapuser


有效了!现在我们试试用错误密码登录会不会验证失败?


docker-compose exec clickhouse1 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser2" -q "SELECT user()"'


Code: 516. DB::Exception: Received from localhost:9000. DB::Exception: ldapuser: Authentication failed: password is incorrect or there is no user with such name.


删除用户的配置文件,接下来我们改用RBAC定义Clickhouse用户


docker-compose exec clickhouse1 bash -c 'rm -rf /etc/clickhouse-server/users.d/ldapuser.xml'




使用RBAC定义经过LDAP Server验证的用户


在Clickhouse中,除XML配置文件之外,我们还可使用RBAC命令以更简单的方式定义用户。我们建议使用RBAC命令,因为您可使用ON CLUSTER语句在整个Clickhouse集群上创建或删除用户。


CREATE USER命令的语法定义如下。


CREATE USER [IF NOT EXISTS | OR REPLACE] name1 [ON CLUSTER cluster_name1]   
        [, name2 [ON CLUSTER cluster_name2] ...]  
    [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}]  
    [HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]  
    [DEFAULT ROLE role [,...]]  
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]


现在您还可以使用IDENTIFIED WITH LDAP_SERVER语句,绑定LDAP Server对该用户进行身份验证。


docker-compose exec clickhouse1 bash -c 'clickhouse-client -q "CREATE USER ldapuser IDENTIFIED WITH LDAP_SERVER BY '\''openldap1'\''"'


检查用户是否创建成功


docker-compose exec clickhouse1 bash -c 'clickhouse-client -q "SHOW USERS"'


default  
ldapuser


使用ldapuser用户执行查询。


docker-compose exec clickhouse1 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT user()"'


ldapuser


使用错误密码登录看看会不会报错


docker-compose exec clickhouse1 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser2" -q "SELECT user()"'


Code: 516. DB::Exception: Received from localhost:9000. DB::Exception: ldapuser: Authentication failed: password is incorrect or there is no user with such name.




在集群中使用RBAC定义经过LDAP Server验证的用户


RBAC命令允许在群集上创建或删除用户。现在我们将LDAP Server配置添加到其他两个ClickHouse节点:clickhouse2clickhouse3


首先,将LDAP Server配置添加到clickhouse2


docker-compose exec clickhouse2 bash -c 'cat <<HEREDOC > /etc/clickhouse-server/config.d/ldap_servers.xml  
<?xml version="1.0" encoding="utf-8"?>  
<yandex>  
  <ldap_servers>  
    <!--LDAP servers b9f1f80c_6598_11eb_80c1_39d7fbdc1e26-->  
    <openldap1>  
      <host>openldap1</host>  
      <port>636</port>  
      <enable_tls>yes</enable_tls>  
      <auth_dn_prefix>cn=</auth_dn_prefix>  
      <auth_dn_suffix>,ou=users,dc=company,dc=com</auth_dn_suffix>  
      <tls_require_cert>never</tls_require_cert>  
    </openldap1>  
  </ldap_servers>  
</yandex>  
HEREDOC'


clickhouse3也进行同样的操作


docker-compose exec clickhouse3 bash -c 'cat <<HEREDOC > /etc/clickhouse-server/config.d/ldap_servers.xml  
<?xml version="1.0" encoding="utf-8"?>  
<yandex>  
  <ldap_servers>  
    <!--LDAP servers b9f1f80c_6598_11eb_80c1_39d7fbdc1e26-->  
    <openldap1>  
      <host>openldap1</host>  
      <port>636</port>  
      <enable_tls>yes</enable_tls>  
      <auth_dn_prefix>cn=</auth_dn_prefix>  
      <auth_dn_suffix>,ou=users,dc=company,dc=com</auth_dn_suffix>  
      <tls_require_cert>never</tls_require_cert>  
    </openldap1>  
  </ldap_servers>  
</yandex>  
HEREDOC'


现在,我们将ON CLUSTER子句添加到CREATE USER命令中,在集群上创建ldapuser用户


docker-compose exec clickhouse1 bash -c 'clickhouse-client -q "CREATE USER IF NOT EXISTS ldapuser IDENTIFIED WITH LDAP_SERVER BY '\''openldap1'\'' ON CLUSTER '\''replicated_cluster'\''"'


clickhouse2 9000 0  2 0  
clickhouse1 9000 0  1 0  
clickhouse3 9000 0  0 0


现在,我们以ldapuser用户登录到集群的每个节点上执行命令。


docker-compose exec clickhouse1 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT user()"'  
docker-compose exec clickhouse2 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT user()"'  
docker-compose exec clickhouse3 bash -c 'clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT user()"'




优化LDAP身份验证用户的登录


在使用LDAP Server对用户进行身份验证后,每次用户登录Clickhouse时,ClickHouse都必须请求LDAP Server来对该用户进行验证。当许多用户都需要身份验证时,这可能不是最佳选择。


为了解决此问题,我们可在Clickhouse的LDAP Server配置中使用<verification_cooldown>参数,该参数指定一次成功登录之后的时间(单位:秒):在此期间,对于连续请求中的用户,我们将假定其已被成功验证, 这样就无需每次都请求LDAP Server。


默认情况下,此参数为0,表示禁用缓存,即每次用户登录时Clickhouse都会请求LDAP Server进行身份验证。


当前缓存已被禁用。我们在clickhouse1上进行基准测试:


docker-compose exec clickhouse1 bash -c 'time for n in {1..1000}; do clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT 1" > /dev/null; done'


real  0m30.189s  
user  0m14.492s  
sys   0m9.847s


接着我们在clickhouse1上更改<verification_cooldown>参数,改成5分钟


docker-compose exec clickhouse1 bash -c 'cat <<HEREDOC > /etc/clickhouse-server/config.d/ldap_servers.xml  
<?xml version="1.0" encoding="utf-8"?>  
<yandex>  
  <ldap_servers>  
    <!--LDAP servers b9f1f80c_6598_11eb_80c1_39d7fbdc1e26-->  
    <openldap1>  
      <host>openldap1</host>  
      <port>636</port>  
      <enable_tls>yes</enable_tls>  
      <verification_cooldown>300</verification_cooldown>  
      <auth_dn_prefix>cn=</auth_dn_prefix>  
      <auth_dn_suffix>,ou=users,dc=company,dc=com</auth_dn_suffix>  
      <tls_require_cert>never</tls_require_cert>  
    </openldap1>  
  </ldap_servers>  
</yandex>  
HEREDOC'


启用缓存之后,基准测试结果如下:


docker-compose exec clickhouse1 bash -c 'time for n in {1..1000}; do clickhouse-client -n --user "ldapuser" --password "ldapuser" -q "SELECT 1" > /dev/null; done'


real  0m22.472s  
user  0m12.000s  
sys   0m8.894s


如上所示,通过降低Clickhouse重复请求LDAP Server进行身份验证的开销,我们使用户登录性能提高了约26%。




结论


在本文中,我们介绍了对LDAP与ClickHouse集成的支持。我们研究了如何将LDAP Server配置添加到ClickHouse中。


我们还研究了最简单的情况,即使用LDAP Sever对Clickhouse中定义的用户进行身份验证,无论用户是管理员通过XML文件或RBAC命令配置的。RBAC命令提供对ON CLUSTER语句的支持,有了ON CLUSTER可在整个集群上创建或删除用户,而无需修改集群中每个节点的配置文件。


最后,我们研究了如何启用LDAP用户身份验证的缓存以优化用户重复登录Clickhouse的性能。


相关文章
|
1月前
|
分布式计算 大数据 Apache
ClickHouse与大数据生态集成:Spark & Flink 实战
【10月更文挑战第26天】在当今这个数据爆炸的时代,能够高效地处理和分析海量数据成为了企业和组织提升竞争力的关键。作为一款高性能的列式数据库系统,ClickHouse 在大数据分析领域展现出了卓越的能力。然而,为了充分利用ClickHouse的优势,将其与现有的大数据处理框架(如Apache Spark和Apache Flink)进行集成变得尤为重要。本文将从我个人的角度出发,探讨如何通过这些技术的结合,实现对大规模数据的实时处理和分析。
131 2
ClickHouse与大数据生态集成:Spark & Flink 实战
|
2月前
|
存储 JavaScript 数据库
ToB项目身份认证AD集成(一):基于目录的用户管理、LDAP和Active Directory简述
本文介绍了基于目录的用户管理及其在企业中的应用,重点解析了LDAP协议和Active Directory服务的概念、关系及差异。通过具体的账号密码认证时序图,展示了利用LDAP协议与AD域进行用户认证的过程。总结了目录服务在现代网络环境中的重要性,并预告了后续的深入文章。
|
4月前
|
jenkins Devops 持续交付
jenkins学习笔记之七:jenkins集成LDAP用户认证
jenkins学习笔记之七:jenkins集成LDAP用户认证
|
6月前
|
SQL 缓存 关系型数据库
ClickHouse(19)ClickHouse集成Hive表引擎详细解析
Hive引擎允许对HDFS Hive表执行 `SELECT` 查询。目前它支持如下输入格式: -文本:只支持简单的标量列类型,除了 `Binary` - ORC:支持简单的标量列类型,除了`char`; 只支持 `array` 这样的复杂类型 - Parquet:支持所有简单标量列类型;只支持 `array` 这样的复杂类型
227 1
|
6月前
|
SQL NoSQL 关系型数据库
ClickHouse(24)ClickHouse集成mongodb表引擎详细解析
**MongoDB引擎在ClickHouse中提供只读访问远程数据,用于`SELECT`查询。不支持写入。创建MongoDB表引擎的语法:`CREATE TABLE ... ENGINE = MongoDB(host, db, coll, user, pass)`。例如:**查看[ClickHouse中文文档](https://zhangfeidezhu.com/?p=468)获取更多教程,包括系列文章覆盖的各种表引擎解析。
162 0
|
6月前
|
SQL 关系型数据库 MySQL
ClickHouse(23)ClickHouse集成Mysql表引擎详细解析
ClickHouse的MySQL引擎允许执行`SELECT`查询从远程MySQL服务器。使用`MySQL(&#39;host:port&#39;, &#39;database&#39;, &#39;table&#39;, &#39;user&#39;, &#39;password&#39;[,...])`格式连接,支持简单`WHERE`子句在MySQL端处理,复杂条件和`LIMIT`在ClickHouse端执行。不支持`NULL`值,用默认值替换。系列文章涵盖ClickHouse安装、集群搭建、表引擎解析等主题。[链接](https://zhangfeidezhu.com/?p=468)有更多
277 0
|
6月前
|
安全 Java 数据安全/隐私保护
Spring Boot中集成LDAP身份认证的步骤
Spring Boot中集成LDAP身份认证的步骤
|
6月前
|
SQL 分布式计算 安全
ClickHouse(22)ClickHouse集成HDFS表引擎详细解析
ClickHouse的HDFS引擎允许直接在Hadoop生态系统内管理数据。使用`ENGINE=HDFS(URI, format)`,其中URI指定HDFS路径,format定义文件格式(如TSV、CSV或ORC)。表可读写,但不支持`ALTER`、`SELECT...SAMPLE`、索引和复制操作。通配符可用于文件路径,如`*`、`?`和范围`{N..M}`。Kerberos认证可配置。虚拟列包括文件路径 `_path` 和文件名 `_file`。有关更多信息,参见相关文章系列。
169 0
|
6月前
|
消息中间件 SQL 存储
ClickHouse(21)ClickHouse集成Kafka表引擎详细解析
ClickHouse的Kafka表引擎允许直接从Apache Kafka流中消费数据,支持多种数据格式如JSONEachRow。创建Kafka表时需指定参数如brokers、topics、group和format。关键参数包括`kafka_broker_list`、`kafka_topic_list`、`kafka_group_name`和`kafka_format`。Kafka特性包括发布/订阅、容错存储和流处理。通过设置`kafka_num_consumers`可以调整并行消费者数量。Kafka引擎还支持Kerberos认证。虚拟列如`_topic`、`_offset`等提供元数据信息。
255 0
|
6月前
|
SQL 关系型数据库 数据库连接
ClickHouse(20)ClickHouse集成PostgreSQL表引擎详细解析
ClickHouse的PostgreSQL引擎允许直接查询和插入远程PostgreSQL服务器的数据。`CREATE TABLE`语句示例展示了如何定义这样的表,包括服务器信息和权限。查询在只读事务中执行,简单筛选在PostgreSQL端处理,复杂操作在ClickHouse端完成。`INSERT`通过`COPY`命令在PostgreSQL事务中进行。注意,数组类型的处理和Nullable列的行为。示例展示了如何从PostgreSQL到ClickHouse同步数据。一系列的文章详细解释了ClickHouse的各种特性和表引擎。
194 0