【譯】Clickhouse與LDAP集成(一)


更多精彩內容,請關注微信公眾號:后端技術小屋

原文:https://altinity.com/blog/integrating-clickhouse-with-ldap-part-one
作者:Vitaliy Zakaznikov

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

請繼續關注下一部分,我們將討論如何將LDAP Server用作外部用戶目錄,從而無需在ClickHouse中定義用戶。如果您還有其他疑問或想討論您的安全需求,請隨時通過info@altinity.com與我們聯系。我們很樂意為您提供幫助!

推薦閱讀

更多精彩內容,請掃碼關注微信公眾號:后端技術小屋。如果覺得文章對你有幫助的話,請多多分享、轉發、在看。

二維碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM