ON CLUSTER 子句支持在集群中创建用户,参见 分布式 DDL。
身份标识
IDENTIFIED WITH no_passwordIDENTIFIED WITH plaintext_password BY 'qwerty'IDENTIFIED WITH sha256_password BY 'qwerty'orIDENTIFIED BY 'password'IDENTIFIED WITH sha256_hash BY 'hash'orIDENTIFIED WITH sha256_hash BY 'hash' SALT 'salt'IDENTIFIED WITH double_sha1_password BY 'qwerty'IDENTIFIED WITH double_sha1_hash BY 'hash'IDENTIFIED WITH bcrypt_password BY 'qwerty'IDENTIFIED WITH bcrypt_hash BY 'hash'IDENTIFIED WITH ldap SERVER 'server_name'IDENTIFIED WITH kerberosorIDENTIFIED WITH kerberos REALM 'realm'IDENTIFIED WITH ssl_certificate CN 'mysite.com:user'IDENTIFIED WITH ssh_key BY KEY 'public_key' TYPE 'ssh-rsa', KEY 'another_public_key' TYPE 'ssh-ed25519'IDENTIFIED WITH http SERVER 'http_server'orIDENTIFIED WITH http SERVER 'http_server' SCHEME 'basic'IDENTIFIED BY 'qwerty'
在 ClickHouse Cloud 中,默认情况下,密码必须满足以下复杂度要求:
- 长度至少为 12 个字符
- 至少包含 1 个数字
- 至少包含 1 个大写字母
- 至少包含 1 个小写字母
- 至少包含 1 个特殊字符
示例
-
以下用户名为
name1,且无需密码——显然,这样几乎没有什么安全性可言: -
要指定明文密码:
-
最常见的做法是使用经过 SHA-256 哈希处理的密码。当你指定
IDENTIFIED WITH sha256_password时,ClickHouse 会自动为你计算密码哈希。例如:现在,name3用户可以使用my_password登录,但密码实际以上面的哈希值形式存储。系统会在/var/lib/clickhouse/access中创建以下 SQL 文件,并在服务器启动时执行:
-
double_sha1_password通常并不常用,但在配合需要它的客户端时会很有帮助 (例如 MySQL 接口) :ClickHouse 会生成并执行以下查询: -
bcrypt_password是存储密码时最安全的选项。它使用 bcrypt 算法,即使密码哈希泄露,也能有效抵御暴力破解攻击。使用此方法时,密码长度限制为 72 个字符。 bcrypt work factor 参数用于定义计算哈希和验证密码所需的计算量与时间,可在服务器配置中修改:work factor 必须介于 4 到 31 之间,默认值为 12。
-
也可以省略密码类型:
在这种情况下,ClickHouse 将使用服务器配置中指定的默认密码类型:可用的密码类型有:
plaintext_password、sha256_password、double_sha1_password。 -
可以指定多种身份验证方法:
- 较旧版本的 ClickHouse 可能不支持多种身份验证方法的语法。因此,如果 ClickHouse 服务器 中存在此类用户,而又被降级到不支持该语法的版本,这些用户将无法使用,并且部分与用户相关的操作也会失效。为了平稳降级,必须在降级前将所有用户都设置为仅包含一种身份验证方法。或者,如果 server 未按正确流程就已降级,则应删除这些有问题的用户。
- 出于安全原因,
no_password不能与其他身份验证方法同时存在。因此,只有当它是查询中唯一的身份验证方法时,您才可以指定no_password。
用户主机
HOST 部分中按以下方式指定主机:
HOST IP 'ip_address_or_subnetwork'— 用户只能从指定的 IP 地址或某个子网连接到 ClickHouse 服务器。示例:HOST IP '192.168.0.0/16'、HOST IP '2001:DB8::/32'。在生产环境中,建议仅指定HOST IP元素 (IP 地址及其掩码) ,因为使用host和host_regexp可能会带来额外延迟。HOST ANY— 用户可以从任何位置连接。这是默认选项。HOST LOCAL— 用户只能在本地连接。HOST NAME 'fqdn'— 用户主机可以指定为 FQDN。例如:HOST NAME 'mysite.com'。HOST REGEXP 'regexp'— 指定用户主机时,可以使用 pcre 正则表达式。例如:HOST REGEXP '.*\.mysite\.com'。HOST LIKE 'template'— 允许使用 LIKE 运算符来过滤用户主机。例如,HOST LIKE '%'等同于HOST ANY,HOST LIKE '%.mysite.com'会过滤mysite.com域下的所有主机。
@ 语法。示例:
CREATE USER mira@'127.0.0.1'— 等同于HOST IP语法。CREATE USER mira@'localhost'— 等同于HOST LOCAL语法。CREATE USER mira@'192.168.%.%'— 等同于HOST LIKE语法。
VALID UNTIL 子句
YYYY-MM-DD [hh:mm:ss] [timezone] 格式,其中 [timezone] 必须是数值偏移量 (如 +09:00) ,或 UTC、GMT、Z、MSK、MSD 之一;不支持 Asia/Tokyo 这类命名 IANA 时区 (请参阅下方说明) 。默认情况下,此参数为 'infinity'。可接受的截止时间范围为 1900-01-01 00:00:00 UTC 至 9999-12-31 09:59:59 UTC——后者是在所有时区中均仍处于 9999 年内的最晚时刻,因此存储的时刻在显示时绝不会被截断。过去的截止时间表示凭据已过期。早于 1970-01-01 00:00:01 UTC 的截止时间仅会作为“已过期”标记被接受:它们会被规范化为最早的过期时刻,即 Unix 纪元后一秒 (1970-01-01 00:00:01 UTC) ,因此 SHOW CREATE USER 显示的是该时刻,而非您指定的截止时间。自该时刻起的截止时间将按原样存储。
截止时间以绝对时刻存储,但 SHOW CREATE USER 和 system.users 会按服务器或会话时区显示它,因此同一存储时刻在配置不同的服务器上会显示为不同的本地时间文本:例如,上述规范化后的过期时刻在 UTC 服务器上显示为 1970-01-01 00:00:01,在 Pacific/Kiritimati 服务器上则显示为 1970-01-01 14:00:01。实际执行时始终使用存储的时刻,而非其显示结果。
子句的位置决定其适用的身份验证方法:
- 位于
IDENTIFIED子句之前 (或查询完全未指定身份验证方法时) :截止时间为用户级截止时间,适用于该用户的所有身份验证方法。 - 位于某个身份验证方法之后:截止时间仅适用于该方法。因此,写在整个
IDENTIFIED列表之后的子句只会绑定到最后一个方法,之前的方法不会过期。
CREATE USER name1 VALID UNTIL '2025-01-01'CREATE USER name1 VALID UNTIL '2025-01-01 12:00:00 UTC'CREATE USER name1 VALID UNTIL '2025-01-01 12:00:00 +09:00'CREATE USER name1 VALID UNTIL 'infinity'CREATE USER name1 VALID UNTIL '2025-01-01' IDENTIFIED WITH plaintext_password BY 'password_1', bcrypt_password BY 'password_2'— 用户级截止时间适用于两种方法。CREATE USER name1 IDENTIFIED WITH plaintext_password BY 'no_expiration', bcrypt_password BY 'expiration_set' VALID UNTIL '2025-01-01'— 截止时间仅适用于bcrypt_password方法;plaintext_password永不过期。
日期时间字符串由
parseDateTimeBestEffort 解析,该函数仅识别时区标记 UTC、GMT、Z、MSK、MSD,以及 +09:00 或 -05:00 等数值偏移量。不支持 Asia/Tokyo 或 Europe/London 这类命名 IANA 时区;对于采用夏令时的区域,固定偏移量并不等同于 IANA 时区,因此必须根据要编码的具体日期计算正确的偏移量。VALID FOR 子句
VALID FOR 子句是 VALID UNTIL 的便捷简写。它不使用绝对日期和时间,而是接受一个时间间隔,并在执行查询时将过期截止时间计算为当前时间加上该时间间隔。结果随后以 VALID UNTIL 形式存储,因此 SHOW CREATE USER 始终显示解析出的绝对截止时间。它可在任何可使用 VALID UNTIL 的位置使用,并遵循相同的放置规则:位于 IDENTIFIED 之前 (或未指定身份验证方法时) 时,它是适用于所有方法的用户级截止时间;位于某个身份验证方法之后时,则仅适用于该方法。截止时间以秒级精度存储和强制执行,因此不接受亚秒级时间间隔 (NANOSECOND、MICROSECOND、MILLISECOND) ;可接受的最小单位为 SECOND。负时间间隔可用于将凭据标记为已过期;如果计算得到的截止时间早于 1970-01-01 00:00:01 UTC,则会将其规范化为该最早的过期时刻,之后 SHOW CREATE USER 将报告该时刻——如 VALID UNTIL 所述,它会以服务器或会话时区显示。
示例:
CREATE USER name1 VALID FOR INTERVAL 1 DAYCREATE USER name1 VALID FOR INTERVAL 3 MONTHCREATE USER name1 VALID FOR INTERVAL 1 DAY + INTERVAL 12 HOURCREATE USER name1 VALID FOR INTERVAL 30 DAY IDENTIFIED WITH plaintext_password BY 'password_1', bcrypt_password BY 'password_2'— 用户级截止时间适用于这两种方法。CREATE USER name1 IDENTIFIED WITH plaintext_password BY 'no_expiration', bcrypt_password BY 'expiration_set' VALID FOR INTERVAL 30 DAY— 截止时间仅适用于bcrypt_password方法;plaintext_password永不过期。
GRANTS 子句
VALID UNTIL 子句,则位于其后) ,且仅适用于该方法。
当用户通过此类身份验证方法登录时,会话的访问权限是用户访问权限 (包括已获授角色的权限) 与子句中列出特权的交集。该子句绝不会增加任何访问权限:如果列出的特权未授予该用户,会话便不具备该特权。通过此类方法进行身份验证的会话也不能授予特权 (GRANT OPTION 永远不会保留在交集中) ,也不能管理角色。管理角色不仅包括创建、修改、删除、授予和撤销角色,还包括更改默认情况下为用户激活的角色 (SET DEFAULT ROLE 和 ALTER USER ... DEFAULT ROLE) ;这些操作同样会被拒绝。
EXECUTE AS 会切换会话的主体,因此,以模拟身份运行的语句受目标用户访问权限与所列特权交集的限制,而非登录用户的权限限制。该限制本身永远不会解除;此外,模拟身份要求 IMPERSONATE ON target 同时已授予该用户并列在子句中。因此,受限凭据的权限范围绝不会超过同一用户的不受限凭据。
这为应用程序创建标记提供了一种便捷方式:创建一个绑定到该用户、具有到期日期和有限特权集的额外凭据。它会在 system.query_log 和 system.processes 中显示为该用户;用户被删除后便无法再使用;用户失去访问权限时,它也会失去相应权限。
示例:
CREATE USER name1 IDENTIFIED BY 'qwerty' GRANTS (SELECT ON db.*)ALTER USER name1 ADD IDENTIFIED WITH plaintext_password BY 'app_token' VALID UNTIL '2026-12-31' GRANTS (SELECT ON db.table, INSERT ON db.table)
ALTER USER 更改子句只会影响新会话,不会影响已建立的会话。
该子句暂不支持带过滤器的源授权,例如 READ ON S3('s3://bucket/.*'):交集会将源过滤器视为不透明字符串进行比较,无法将一个过滤器缩小为另一个过滤器,因此此类授权会被拒绝,而不会静默地导致不授予任何访问权限。
该子句仅支持凭据完全由服务器本地验证的身份验证方法。对于验证时会联系外部系统的方法 (对于 jwt,则可能会联系外部系统,例如获取签名密钥) (ldap、kerberos、http、jwt) ,该子句会被拒绝:当多个身份验证方法接受同一凭据时,限制通过根据其他方法重新检查凭据来强制执行;额外探测外部系统并不安全,因此接受同一凭据的其他方法可能绕过该限制。
当同一有效凭据被多个身份验证方法接受时,登录会以故障关闭的方式受所有这些方法限制:会话获得所有匹配方法的 GRANTS 的交集,并在最早的 VALID UNTIL 时到期。即使最早的 VALID UNTIL 已经过期,它仍然优先:登录会被拒绝,就如同唯一匹配的方法已过期一样。因此,标记过期绝不会悄然使共享凭据获得更宽泛方法的权限或有效期。
出于同样的原因,此组合仅在由 服务器 本地验证的身份验证方法之间进行检查:如上所述,对于外部验证的方法,该子句本身会被拒绝,因为重新检查凭据需要对外部系统进行一次不安全的额外探测。因此,如果同一用户的外部验证方法 (ldap、kerberos、http、jwt) 恰好也接受相同的凭据,则该方法自身的 VALID UNTIL 不会纳入此组合,为其配置的较早到期时间也不会缩短通过本地验证方法获得的 会话。
GRANTEES 子句
GRANTEES 子句的选项包括:
user— 指定该用户可以向其授予权限的用户。role— 指定该用户可以向其授予权限的角色。ANY— 该用户可以向任何人授予权限。这是默认设置。NONE— 该用户不能向任何人授予权限。
EXCEPT 表达式来排除任意用户或角色。例如,CREATE USER user1 GRANTEES ANY EXCEPT user2。这表示如果 user1 拥有某些通过 GRANT OPTION 授予的权限,它就能够将这些权限授予除 user2 之外的任何人。
示例
mira,并使用密码 qwerty 进行保护:
mira 应在运行 ClickHouse 服务器的主机上启动客户端应用程序。
创建用户账户 john 并分配角色:
john,分配角色,并将其中部分角色设为默认:
john,并允许他将自己的权限授予 jack 用户账户:
john: