【译】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的性能。


相关文章
|
3月前
|
SQL 关系型数据库 MySQL
ClickHouse(18)ClickHouse集成ODBC表引擎详细解析
ClickHouse使用ODBC集成表引擎通过`clickhouse-odbc-bridge`安全连接外部数据库,支持Nullable类型。创建ODBC表引擎的SQL示例:`CREATE TABLE ... ENGINE = ODBC(connection_settings, db, table)`. 用户需配置`odbc.ini`,如在Ubuntu+MySQL上,为`clickhouse`用户授予权限。查询示例展示如何从MySQL检索数据到ClickHouse。查阅更多详情:[ClickHouse经典中文文档分享](https://zhangfeidezhu.com/?p=468)。
62 12
|
3月前
|
Java 关系型数据库 MySQL
ClickHouse(17)ClickHouse集成JDBC表引擎详细解析
ClickHouse通过JDBC桥接器`clickhouse-jdbc-bridge`连接到外部数据库,支持Nullable类型。使用`CREATE TABLE`语句配置JDBC引擎,如`ENGINE = JDBC(datasource_uri, db, table)`。示例展示了如何与MySQL交互,创建本地表并从远程MySQL表中查询和插入数据。此外,ClickHouse还支持JDBC表函数,允许临时查询远程表。相关系列文章在指定链接中提供。
246 7
|
14天前
|
jenkins Devops 持续交付
jenkins学习笔记之七:jenkins集成LDAP用户认证
jenkins学习笔记之七:jenkins集成LDAP用户认证
|
3月前
|
SQL 缓存 关系型数据库
ClickHouse(19)ClickHouse集成Hive表引擎详细解析
Hive引擎允许对HDFS Hive表执行 `SELECT` 查询。目前它支持如下输入格式: -文本:只支持简单的标量列类型,除了 `Binary` - ORC:支持简单的标量列类型,除了`char`; 只支持 `array` 这样的复杂类型 - Parquet:支持所有简单标量列类型;只支持 `array` 这样的复杂类型
145 1
|
3月前
|
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)获取更多教程,包括系列文章覆盖的各种表引擎解析。
94 0
|
3月前
|
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)有更多
146 0
|
3月前
|
安全 Java 数据安全/隐私保护
Spring Boot中集成LDAP身份认证的步骤
Spring Boot中集成LDAP身份认证的步骤
|
3月前
|
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`。有关更多信息,参见相关文章系列。
68 0
|
3月前
|
消息中间件 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`等提供元数据信息。
169 0
|
3月前
|
SQL 关系型数据库 数据库连接
ClickHouse(20)ClickHouse集成PostgreSQL表引擎详细解析
ClickHouse的PostgreSQL引擎允许直接查询和插入远程PostgreSQL服务器的数据。`CREATE TABLE`语句示例展示了如何定义这样的表,包括服务器信息和权限。查询在只读事务中执行,简单筛选在PostgreSQL端处理,复杂操作在ClickHouse端完成。`INSERT`通过`COPY`命令在PostgreSQL事务中进行。注意,数组类型的处理和Nullable列的行为。示例展示了如何从PostgreSQL到ClickHouse同步数据。一系列的文章详细解释了ClickHouse的各种特性和表引擎。
98 0