Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

将 Windows Active Directory 安全组映射为 ClickHouse 角色

示例

本示例展示了如何为隶属于不同 AD 安全组的 AD 用户授予 ClickHouse 中相应角色的访问权限。它还展示了如何将同一用户添加到多个 AD 用户组中,从而获得多个角色授予的访问权限。

在此环境中,包含以下内容:

  • 一个 Windows Active Directory 域:marsnet2.local
  • 一个 ClickHouse 集群 cluster_1S_3R,包含 3 个节点,集群配置为 1 个分片、3 个副本
  • 3 个 AD 用户
AD 用户 描述
clickhouse_ad_admin ClickHouse 管理员用户
clickhouse_db1_user 具有 db1.table1 访问权限的用户
clickhouse_db2_user 具有 db2.table1 访问权限的用户
ch_db1_db2_user 同时具有 db1.table1 和 db2.table1 访问权限的用户
  • 3 个 AD 安全组
AD 组 描述
clickhouse_ad_admins ClickHouse 管理员组
clickhouse_ad_db1_users 用于映射 db1.table1 访问权限的组
clickhouse_ad_db2_users 用于映射 db2.table1 访问权限的组
  • 示例 AD 环境和 OU 结构:
示例 AD 环境和 OU 结构
  • 示例 AD 安全组配置:
示例 AD 安全组配置
  • 示例 AD 用户配置:
示例 AD 用户配置
  1. 在 Windows AD Users and Groups 中,将每个用户添加到各自对应的组;这些组会映射到 ClickHouse 角色 (示例见下一步) 。
AD 安全组 ClickHouse 角色
clickhouse_ad_admin clickhouse_ad_admins
clickhouse_db1_user clickhouse_ad_db1_users
clickhouse_db2_user clickhouse_ad_db2_users
ch_db1_db2_user clickhouse_ad_db1_users and clickhouse_ad_db2_users
  • 示例用户组成员关系:
示例用户组成员关系
  1. 在 ClickHouse 的 config.xml 中,为每个 ClickHouse 节点添加 ldap_servers 配置。
<ldap_servers>
	<marsnet2_ad>
		<host>marsdc1.marsnet2.local</host>
		<port>389</port>
		<bind_dn>{user_name}@marsnet2.local</bind_dn>
		<user_dn_detection>
			<base_dn>OU=Users,OU=ClickHouse,DC=marsnet2,DC=local</base_dn>
			<search_filter>(&amp;(objectClass=user)(sAMAccountName={user_name}))</search_filter>
		</user_dn_detection>
		<enable_tls>no</enable_tls>
	</marsnet2_ad>
</ldap_servers>
xml tag 描述 示例值
ldap_servers 用于定义 ClickHouse 将使用的 LDAP 服务器的标签 NA
marsnet_ad 此标签可任意命名,仅作为在 <user_directories> 部分中标识该服务器的标签 NA
host Active Directory 服务器或域的 FQDN 或 IP 地址 marsdc1.marsnet2.local
port Active Directory 端口,通常非 SSL 为 389,SSL 为 636 389
bind_dn 用于与 AD 建立绑定的用户;如果普通用户不允许绑定,也可以使用专用用户 {user_name}@marsnet2.local
user_dn_detection ClickHouse 查找 AD 用户方式的相关设置 NA
base_dn 开始搜索用户的 AD OU 路径 OU=Users,OU=ClickHouse,DC=marsnet2,DC=local
search_filter 用于查找 AD 用户的 LDAP 搜索过滤器 (&(objectClass=user)(sAMAccountName={user_name}))

有关完整选项,请参阅文档: https://clickhouse.com/docs/operations/external-authenticators/ldap#ldap-server-definition

  1. 在 ClickHouse config.xml 中,为每个 ClickHouse 节点添加包含 <ldap> 条目的 <user_directories> 配置。
<user_directories>
	<users_xml>
		<path>users.xml</path>
	</users_xml>
	<local_directory>
		<path>/var/lib/clickhouse/access/</path>
	</local_directory>
	<ldap>
		<server>marsnet2_ad</server>
		<role_mapping>
			<base_dn>OU=Groups,OU=ClickHouse,DC=marsnet2,DC=local</base_dn>
			<search_filter>(&amp;(objectClass=group)(member={user_dn}))</search_filter>
			<attribute>CN</attribute>
			<scope>subtree</scope>
			<prefix>clickhouse_</prefix>
		</role_mapping>
	</ldap>
</user_directories>
xml tag 说明 示例值
user_directories 定义要使用哪些身份验证器 NA
ldap 包含要使用的 LDAP 服务器设置 (在此 AD 中) NA
server <ldap_servers> 部分中定义的标签 marsnet2_ad
role_mapping 定义已认证用户如何在 AD 组与 ClickHouse 角色之间进行映射 NA
base_dn 系统用于开始搜索 AD 组的 AD 路径 OU=Groups,OU=ClickHouse,DC=marsnet2,DC=local
search_filter 用于查找 AD 组的 LDAP 搜索过滤器 (&(objectClass=group)(member={user_dn}))
attribute 用于标识用户的 AD 属性字段 CN
scope 系统应在 base DN 的哪些层级中搜索组 subtree
prefix AD 中组名称的前缀;移除此前缀后,系统会查找 ClickHouse 中对应的角色 clickhouse_

有关完整选项,请参阅文档: https://clickhouse.com/docs/operations/external-authenticators/ldap#ldap-external-user-directory

note::: 由于示例中的 AD 安全组带有前缀——即 clickhouse_ad_db1_users——系统检索到这些组后会移除该前缀,并查找名为 ad_db1_users 的 ClickHouse 角色,将其映射到 clickhouse_ad_db1_users:::

  1. 创建示例数据库。
create database db1 on cluster 'cluster_1S_3R';
create database db2 on cluster 'cluster_1S_3R';
  1. 创建示例表。
create table db1.table1 on cluster 'cluster_1S_3R'
(
  id Int32,
  column1 String
)
engine = MergeTree()
order by id;

create table db2.table1 on cluster 'cluster_1S_3R
(
  id Int32,
  column1 String
)
engine = MergeTree()
order by id;
  1. 插入示例数据。
insert into db1.table1
values
(1, 'a');

insert into db2.table1
values
(2, 'b');
  1. 创建 ClickHouse 角色。
create role ad_admins on cluster 'cluster_1S_3R';
create role ad_db1_users on cluster 'cluster_1S_3R';
create role ad_db2_users on cluster 'cluster_1S_3R';
  1. 向这些角色授予权限。
GRANT SHOW, SELECT, INSERT, ALTER, CREATE, DROP, UNDROP TABLE, TRUNCATE, OPTIMIZE, BACKUP, KILL QUERY, KILL TRANSACTION, MOVE PARTITION BETWEEN SHARDS, ACCESS MANAGEMENT, SYSTEM, dictGet, displaySecretsInShowAndSelect, INTROSPECTION, SOURCES, CLUSTER ON *.* on cluster 'cluster_1S_3R' TO ad_admins WITH GRANT OPTION;

GRANT SELECT ON db1.table1 on cluster 'cluster_1S_3R' TO ad_db1_users;

GRANT SELECT ON db2.table1 on cluster 'cluster_1S_3R' TO ad_db2_users;
  1. 测试受限 db1 用户的访问权限。 例如:
root@chnode1:/etc/clickhouse-server# clickhouse-client --user clickhouse_db1_user --password MyPassword123  --secure --port 9440 --host chnode1.marsnet.local
ClickHouse client version 24.1.3.31 (official build).
Connecting to chnode1.marsnet.local:9440 as user clickhouse_db1_user.
Connected to ClickHouse server version 24.1.3.

clickhouse :) select * from db1.table1;

SELECT *
FROM db1.table1

Query id: b04b92d6-5b8b-40a2-a92a-f06f15774930

┌─id─┬─column1─┐
│  1 │ a       │
└────┴─────────┘

1 row in set. Elapsed: 0.004 sec.

clickhouse :) select * from db2.table1;

SELECT *
FROM db2.table1

Query id: 7f7eaa44-7b47-4184-807a-6968a56057ad

Elapsed: 0.115 sec.

Received exception from server (version 24.1.3):
Code: 497. DB::Exception: Received from chnode1.marsnet.local:9440. DB::Exception: clickhouse_db1_user: Not enough privileges. To execute this query, it's necessary to have the grant SELECT(id, column1) ON db2.table1. (ACCESS_DENIED)
  1. 测试可同时访问两个数据库 db1 和 db2 的用户的访问情况。 例如:
root@chnode1:/etc/clickhouse-server# clickhouse-client --user ch_db1_db2_user --password MyPassword123  --secure --port 9440 --host chnode1.marsnet.local
ClickHouse client version 24.1.3.31 (official build).
Connecting to chnode1.marsnet.local:9440 as user ch_db1_db2_user.
Connected to ClickHouse server version 24.1.3.

clickhouse :) select * from db1.table1;

SELECT *
FROM db1.table1

Query id: 23084744-08c2-48bd-8635-a23438812026

┌─id─┬─column1─┐
│  1 │ a       │
└────┴─────────┘

1 row in set. Elapsed: 0.005 sec.

clickhouse :) select * from db2.table1;

SELECT *
FROM db2.table1

Query id: f9954ec4-d8d9-4b5a-9f68-a7aa79a1bb4a

┌─id─┬─column1─┐
│  2 │ b       │
└────┴─────────┘

1 row in set. Elapsed: 0.004 sec.
  1. 测试 Admin 用户的访问权限。 例如:
root@chnode1:/etc/clickhouse-server# clickhouse-client --user clickhouse_ad_admin --password MyPassword123  --secure --port 9440 --host chnode1.marsnet.local
ClickHouse client version 24.1.3.31 (official build).
Connecting to chnode1.marsnet.local:9440 as user clickhouse_ad_admin.
Connected to ClickHouse server version 24.1.3.

clickhouse :) create table db1.table2 on cluster 'cluster_1S_3R'
(
  id Int32,
  column1 String
)
engine = MergeTree()
order by id;

CREATE TABLE db1.table2 ON CLUSTER cluster_1S_3R
(
    `id` Int32,
    `column1` String
)
ENGINE = MergeTree
ORDER BY id

Query id: 6041fd32-4294-44bd-b442-3fdd41333e6f

┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.marsnet.local │ 9440 │      0 │       │                   2 │                2 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │      0 │       │                   1 │                1 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode3.marsnet.local │ 9440 │      0 │       │                   0 │                0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
Navigation