1. 程式人生 > 其它 >clickhouse(七)訪問許可權&賬戶管理

clickhouse(七)訪問許可權&賬戶管理

背景

在之前寫的文章使用者許可權管理裡已經介紹了應該如何設定使用者密碼以及許可權控制。但是隻是針對修改配置檔案的方式來進行使用者許可權管理,其實ClickHouse也支援基於RBAC(Role-BasedAccessControl)的訪問控制管理,即通過SQL-driven來進行管理。在RBAC中,許可權與角色相關聯,通過成為角色的成員而得到這些角色的許可權。簡化了許可權的管理。這樣管理都是層級相互依賴的,許可權賦予給角色,而把角色又賦予使用者,ClickHouse推薦使用該方式進行使用者許可權管理。更多的資訊可以看:訪問許可權和賬戶管理

說明

ClickHouse(version 21.6.3)許可權包括:

-使用者賬戶
-角色
-行策略
-設定描述
-配額

可以通過如下方式配置許可權:

  • 通過SQL-driven的工作流方式,需要手動開啟該功能,預設關閉:
    users.xml:
      
    access_management:1 開啟

        <users>
            <default>
                <password>123456</password>
                <networks>
                    <ip>::/0</ip>
                </networks>
                <profile>default</profile>
                <quota>default</quota>
                <access_management>1</access_management>
    </default> </users>
  • 通過服務端配置檔案users.xmlconfig.xml,像之前的使用者許可權管理文章說明的一樣。

建議使用SQL-driven工作流的方式。當然配置的方式也可以同時起作用, 可以平滑的配置管理方式切換到SQL-driven的工作流方式。

使用

在介紹使用者許可權管理之前,再次瞭解下使用者許可權相關的幾個方面:

  • 許可權的型別
  • 配置組(Profiles)的設定,在users.xml檔案中
  • 限制(constraints)
  • 熔斷(quotas)

一 配置檔案設定

1. 許可權的型別:

ClickHouse中的查詢可以分為幾種型別:

  1. 讀:SELECT,SHOW,DESCRIBE,EXISTS.
  2. 寫:INSERT,OPTIMIZE.
  3. 設定:SET,USE.
  4. DDL:CREATE,ALTER,RENAME,ATTACH,DETACH,DROPTRUNCATE.
  5. KILL:kill 查詢

以下設定按查詢型別規範使用者許可權:

  • readonly— 限制除 DDL 之外的所有查詢型別的許可權

    0:允許所有查詢。
    1:僅允許讀取資料查詢。
    2:允許讀取資料和更改設定查詢。

    預設值0,設定readonly=1 後不能執行readonlyallow_ddl在當前會話中的設定。

  • allow_ddl—限制 DDL 的許可權

    0:不允許 DDL 查詢。
    1:允許 DDL 查詢。

    預設值1,設定 allow_ddl=0 後不能執行 SET allow_ddl = 1。

  • kill —可以使用任何設定執行KILL QUERY

以上的許可權通過配置標籤來控制(users.xml):

<profiles>   --在profiles裡設定
        ...
        <normal> --只讀,不能DDL
            <readonly>1</readonly>
            <allow_ddl>0</allow_ddl>
        </normal>

        <normal_1> --讀且能set,不能DDL
            <readonly>2</readonly>
            <allow_ddl>0</allow_ddl>
        </normal_1>

        <normal_2> --只讀,即使DDL允許
            <readonly>1</readonly>
            <allow_ddl>1</allow_ddl>
        </normal_2>

        <normal_3> --讀寫,能DDL
            <readonly>0</readonly>
            <allow_ddl>1</allow_ddl>
        </normal_3>

    </profiles>

...
    <users>
        ...
        <test>
            <password>123456</password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>normal_3</profile> --使用者引用相關profile
            <quota>default</quota>
        </test>
    </users>
...

2. 配置組(Profiles)的設定:users.xml

profile的作用類似於使用者角色,可以在users.xml中定義多組profile,並可以為每組profile定義不同的配置項:讀、寫、DDL許可權,以及限制的設定,各個profile可以相互繼承。設定好profile之後,可以在使用者中被使用。

<?xml version="1.0"?>
<yandex>
    <profiles>
        <!--自定義profile,可以任意命名-->
        <default>
            <max_memory_usage>100000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <load_balancing>random</load_balancing>
        </default>

        <readonly>
            <readonly>1</readonly>
        </readonly>

        <readwrite>
            <constraints>
                <max_memory_usage>
                    <readonly/>
                </max_memory_usage>
                <force_index_by_date>
                    <readonly/>
                </force_index_by_date>
            </constraints>
        </readwrite>

    </profiles>

...
</yandex>

上面新增profile:readonly 和 readwrite,還可以在命令列裡切換profile:

:) set profile = 'readonly';

切換了profile之後,就擁有了該profile下的許可權。關於配置profile的修改,可以之前的文章【使用者許可權管理】

3. 限制(constraints):

users.xml配置檔案的profile選項組下constraints選項組裡定義設定的約束,並禁止使用者使用SET查詢更改某些設定。constraints標籤可以設定一組約束條件,以限制profile內的引數值被隨意修改,約束條件有如下三種規則:

  • min:最小值約束,在設定相應引數的時候,取值不能小於該閾值;

  • max:最大值約束,在設定相應引數的時候,取值不能大於該閾值;

  • readonly:只讀約束,該引數值不允許被修改。

...
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <force_index_by_date>0</force_index_by_date>
            <load_balancing>random</load_balancing>
        </default>
        <test>
            <constraints>
                <max_memory_usage>
                    <min>100000</min>
                    <max>200000</max>
                </max_memory_usage>
                <force_index_by_date>
                    <readonly/>
                </force_index_by_date>
            </constraints>
        </test>
    </profiles>
...

上面對profile為test進行了限制,如果在該profile下試圖違反約束,則會引發異常並且不會更改設定:

:) SET max_memory_usage=2000000;
-- Code: 452. DB::Exception: Received from localhost:9010. DB::Exception: Setting max_memory_usage shouldn't be greater than 200000.

:) SET max_memory_usage=10000;
-- Code: 452. DB::Exception: Received from localhost:9010. DB::Exception: Setting max_memory_usage shouldn't be less than 100000. 

:) SET force_index_by_date=1;
-- Code: 452. DB::Exception: Received from localhost:9010. DB::Exception: Setting force_index_by_date should not be changed. 

關於限制配置的修改,可以看之前的文章【使用者許可權管理】

4. 配額(quotas)

配合,限制使用資源,類似於熔斷。限制有二種型別:一是在固定週期裡的執行次數(quotas),二是限制使用者或則查詢的使用資源(profiles)。在users.xml配置檔案的選項組quotas裡設定,限制該使用者一段時間內的資源使用,即對一段時間內執行的一組查詢施加限制,而不是限制單個查詢。模板:

    <!-- Quotas. -->
    <quotas>
        <!-- Name of quota. -->
        <default> --指定quotas名
            <!-- Limits for time interval. You could specify many intervals with different limits. -->
            <interval> --時間間隔
                <!-- Length of interval. -->
                <duration>3600</duration> --週期
                <!-- No limits. Just calculate resource usage for time interval. -->
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>

預設情況下,配額僅跟蹤每小時的資源消耗,而沒有限制使用情況。在每個請求之後,將為每個時間間隔計算的資源消耗輸出到伺服器日誌。

說明:

  • <default>:配額規則名。
  • <interval>:配置時間間隔,每個時間內的資源消耗限制。
  • <duration>:時間週期,單位秒。
  • <queries>:時間週期內允許的請求總數,0表示不限制。
  • <errors>:時間週期內允許的異常總數,0表示不限制。
  • <result_rows>:時間週期內允許返回的行數,0表示不限制。
  • <read_rows>:時間週期內允許在分散式查詢中,遠端節點讀取的資料行數,0表示不限制。
  • <execution_time>:時間週期內允許執行的查詢時間,單位是秒,0表示不限制。

關於配額熔斷的配置,可以看之前的文章【使用者許可權管理】

5. 使用者設定

users.xml配置檔案中的users選項組是配置自定義的使用者,定義一個新使用者,必須包含以下幾項屬性:使用者名稱、密碼、訪問ip、資料庫、表等等。它還可以應用上面的profile、constraints、quota。如:

    <users>
        <default>
            <password>123456</password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>

        <zhoujy>
            <password_double_sha1_hex>6bb4837eb74329105ee4568dda7dc67ed2ca2ad9</password_double_sha1_hex>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
            <allow_databases>
                <database>test</database>
            </allow_databases>
            <databases>
                <test>  
                    <xx>
                        <filter>id >= 500 </filter>  --行級限制
                    </xx>
                </test>
            </databases>
        </zhoujy>

    </users>
  • <profile>:指定使用者的profile
  • <quota>:指定使用者的quota,限制使用者使用資源
  • <database_name>:指定使用者訪問的資料庫
  • <table_name>:指定使用者訪問的表
  • <filter>:指定使用者訪問的過濾器,限制返回符合條件的行。如:id = 1 ,即查詢表只返回id=1的行

該示例指定了兩個使用者:

default:指定了密碼、訪問IP、profile、quota。
zhoujy :指定了密碼、訪問IP、profile、quota,以及它只能使用test庫,並且只能返回test庫xx表id大於等於500的資料。

通過以上的設定,已經把使用者許可權的知識點大部分都已經介紹完了,包括了讀寫許可權、許可權的限制和要把這些“規則”應用到使用者上,這樣就完成了使用者許可權的定製了。

以上所有介紹的知識點都可以看之前的文章【使用者許可權管理】,該文章中都做了詳細的說明。通過修改配置檔案雖然能實現ACL,但是比較麻煩,不便於維護管理。所以推薦使用SQL方式進行配置。本文的重點是介紹通過SQL-driven來進行管理使用者許可權。

二 SQL設定

啟用SQL-driven管理需要開啟users.xml檔案中users的引數:

<access_management>1</access_management>

通過SQL-driven設定建立的使用者,都儲存在access目錄中,該目錄的位置是由引數local_directory控制:

        <local_directory>
            <!-- Path to folder where users created by SQL commands are stored. -->
            <!-- <path>/var/lib/clickhouse/access/</path> -->
            <path>/ccdata/clickhouse/access/</path>
        </local_directory>

1.建立使用者(Create User)

CREATE USER 
   [IF NOT EXISTS | OR REPLACE] name1 [ON CLUSTER cluster_name1] [, name2 [ON CLUSTER cluster_name2] ...]
    [NOT IDENTIFIED | IDENTIFIED {[WITH {no_password | plaintext_password | sha256_password | sha256_hash | double_sha1_password | double_sha1_hash}] BY {'password' | 'hash'}} | {WITH ldap SERVER 'server_name'} | {WITH kerberos [REALM 'realm']}]
    [HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
    [DEFAULT ROLE role [,...]]
    [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]

ON CLUSTER 子句允許在叢集上建立使用者。

① 使用者認證:密碼,使用者連線密碼。

  • IDENTIFIED WITH no_password -- 沒有密碼
  • IDENTIFIED WITH plaintext_password BY 'qwerty' -- 明文密碼
  • IDENTIFIED WITH sha256_password BY 'qwerty'orIDENTIFIED BY 'password' --sha256_password 加密密碼
  • IDENTIFIED WITH sha256_hash BY 'hash' --sha256_hash 加密密碼
  • IDENTIFIED WITH double_sha1_password BY 'qwerty' --double_sha1_password 加密密碼
  • IDENTIFIED WITH double_sha1_hash BY 'hash' --double_sha1_hash 加密密碼
  • IDENTIFIED WITH ldap SERVER 'server_name'
  • IDENTIFIED WITH kerberosorIDENTIFIED WITH kerberos REALM 'realm'

② 使用者主機:主機,使用者連線地址。

  • HOST IP 'ip_address_or_subnetwork'— 使用者通過指定IP連線。
  • HOST ANY—可以從任何位置連線,預設。
  • HOST LOCAL— 只能在本地連線。
  • HOST NAME 'fqdn'—使用者主機可以指定為域名。
  • HOST NAME REGEXP 'regexp'— 主機使用正則表示式。
  • HOST LIKE 'template'—使用 LIKE 運算子來過濾使用者主機。 如HOST LIKE '%' 等價於 HOST ANY,HOST LIKE '%.mysite.com' 過濾 mysite.com 域中的所有主機。

指定主機的另一種方法是在使用者名稱後使用@:

  • CREATE USERmira@'127.0.0.1'—等效於 HOST IP 語法
  • CREATE USERmira@'localhost'— 等效於 HOST LOCAL 語法
  • CREATE USERmira@'192.168.%.%'— 等效於 HOST LIKE 語法

③ 授權許可權

通過GRANTEES來授權使用者或則角色,可以獲得建立該使用者的許可權。

  • user—指定可以授予許可權的使用者
  • role—指定可以授予許可權的角色
  • ANY—可以向任何人授予許可權
  • NONE—可以向 none 授予許可權

④:例子

  1. 建立密碼為123456的使用者cc,只能本機登入:
    :) create user cc host ip '127.0.0.1' identified with sha256_password by '123456';
  2. 建立使用者帳戶cao,為其分配角色並將此角色設為預設:
    :) CREATE USER cao DEFAULT ROLE role1, role2;
  3. 建立使用者帳戶 john 並將他未來的所有角色設為預設:
    :) CREATE USER john DEFAULT ROLE ALL;

    當將來某個角色分配給 john 時,它將自動變為預設值。

  4. 建立使用者帳戶 john 並將他未來的所有角色設為預設,除了 role1 和 role2:
    :) CREATE USER john DEFAULT ROLE ALL EXCEPT role1, role2;
  5. 建立使用者帳戶 john 並允許將許可權授給具有 jack 帳戶的使用者:
    :) CREATE USER john GRANTEES jack;

    ----DB::Exception: user `john`: cannot insert because user `john` already exists in local directory: Couldn't insert user `john`. Successfully inserted: none.

2.建立角色(Create Role)

建立角色,角色是一組許可權。分配了角色的使用者獲得該角色的所有許可權。

CREATE ROLE [IF NOT EXISTS | OR REPLACE] name1 [, name2 ...]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]

一個使用者可以分配多個角色。通過 SET ROLE 分配的角色。許可權的範圍是所有應用角色許可權的組合集合。使用者可以擁有適用於使用者登入的預設角色,要設定預設角色,使用SET DEFAULT ROLEALTER USER語句。使用REVOKE來撤銷角色,使用DROP ROLE來刪除角色。

①:建立角色

:) CREATE ROLE zjy;

②:給角色授權

:) GRANT SELECT ON dbtest.* TO zjy;

③:將角色分配給使用者

 :) GRANT zjy TO cc;

④:執行角色擁有的許可權

:) SET ROLE zjy;

:) SELECT * FROM testdb.*;

3.建立行策略(Create ROW POLICY)

建立行策略,即用於確定使用者可以從表中讀取哪些行的過濾器。注意:行策略僅對具有隻讀訪問許可權的使用者有意義。

CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name1 [ON CLUSTER cluster_name1] ON [db1.]table1 
        [, policy_name2 [ON CLUSTER cluster_name2] ON [db2.]table2 ...] 
    [FOR SELECT] USING condition
    [AS {PERMISSIVE | RESTRICTIVE}]
    [TO {role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]}]
  • USING:指定過濾行的條件。 如果該行的條件計算為非零,則使用者將看到該行。
  • TO:應用到適用的使用者和角色。
    如果沒有為表定義行策略,則任何使用者都可以從表中選擇所有行。為表定義一個或多個行策略,無論是否為當前使用者定義了這些行策略,都可以根據行策略訪問表。例如:
    :) CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter;

    禁止使用者 mira 和 peter 檢視 b != 1 的行,任何未提及的使用者(例如,使用者 paul)根本看不到 mydb.table1 中的行。

    CREATE ROW POLICY pol2 ON mydb.table1 USING 1 TO ALL EXCEPT mira, peter

    禁止使用者 mira 和 peter 查看錶資料。

  • AS:允許同時為同一使用者在同一張表上啟用多個策略。所以需要一種方法來組合來自多個策略的條件。
    :) CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter;
    
    :) CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 AS RESTRICTIVE TO peter, antonio;

    當 b=1 和 c=2 時,使用者 peter 才能看到行

eg:

:) CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost;

:) CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira;

:) CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin;

4.建立熔斷配額策略(CREATE QUOTA)

建立可以分配給使用者或角色的配額熔斷策略。

CREATE QUOTA [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name]
    [KEYED BY {user_name | ip_address | client_key | client_key,user_name | client_key,ip_address} | NOT KEYED]
    [FOR [RANDOMIZED] INTERVAL number {second | minute | hour | day | week | month | quarter | year}
        {MAX { {queries | query_selects | query_inserts | errors | result_rows | result_bytes | read_rows | read_bytes | execution_time} = number } [,...] |
         NO LIMITS | TRACKING ONLY} [,...]]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]

關鍵字:user_name、ip_address、client_key、client_key、user_name和client_key、ip_address對應system.quotas表中的欄位。

關鍵字:querys、query_selects、query_inserts、errors、result_rows、result_bytes、read_rows、read_bytes、execution_time對應system.quotas_usage表中的欄位。

①:將當前使用者的最大查詢數限制為 15 個月內123 次:

CREATE QUOTA qA FOR INTERVAL 15 month MAX queries = 123 TO CURRENT_USER;

②:對於預設使用者,在30分鐘之內限制最大執行時間為半秒,將最大查詢數限制為 321,將最大錯誤數限制為 10 :

CREATE QUOTA qB FOR INTERVAL 30 minute MAX execution_time = 0.5, FOR INTERVAL 5 quarter MAX queries = 321, errors = 10 TO default;

在使用者、角色和訪問策略建立好之後,後面就需要授權了。

5.建立配置組策略CREATE SETTINGS PROFILE

建立可分配給使用者或角色的設定配置檔案

CREATE SETTINGS PROFILE [IF NOT EXISTS | OR REPLACE] TO name1 [ON CLUSTER cluster_name1] 
        [, name2 [ON CLUSTER cluster_name2] ...]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...]

eg:

CREATE SETTINGS PROFILE max_memory_usage_profile SETTINGS max_memory_usage = 100000001 MIN 90000000 MAX 110000000 TO robin

使用 max_memory_usage 設定的值和約束建立 max_memory_usage_profile 設定配置檔案,並將其分配給使用者 robin:

6.許可權:許可權是指執行特定操作的許可

許可權有層級結構,一組允許的操作依賴相應的許可權範圍。

級別(由低到高):

  • COLUMN- 可以授權到列,表,庫或者全域性
  • TABLE- 可以授權到表,庫,或全域性
  • VIEW- 可以授權到檢視,庫,或全域性
  • DICTIONARY- 可以授權到字典,庫,或全域性
  • DATABASE- 可以授權到資料庫或全域性
  • GLABLE- 可以授權到全域性
  • GROUP- 不同級別的許可權分組。當授予GROUP級別的許可權時, 根據所用的語法,只有對應分組中的許可權才會被分配。

許可權的層級:

  • SELECT

    允許執行SELECT查詢,許可權級別:COLUMN。

    :) GRANT SELECT(x,y) ON db.table TO john;

    該許可權允許johndb.table表的列x,y執行SELECT查詢。

    :) GRANT SELECT ON db.table TO john;

    該許可權允許johndb.table表的所有列執行SELECT查詢。

  • INSERT

    允許執行INSERT操作,許可權級別:COLUMN。

    :) GRANT INSERT(x,y) ON db.table TO john;

    該許可權允許johndb.table表的列x,y執行資料插入操作

    :) GRANT INSERT ON db.table TO john;

    該許可權允許johndb.table表的所有列執行資料插入操作

  • ALTER
    允許執行ALTER操作
    • ALTER TABLE. 級別:GROUP
      • ALTER UPDATE. 級別:COLUMN. 別名:UPDATE
        :) alter table ttt update address = 'TTTT' where id = 1;
      • ALTER DELETE. 級別:COLUMN. 別名:DELETE
        :) alter table ttt delete where id = 6;
      • ALTER COLUMN. 級別:GROUP
        • ALTER ADD COLUMN. 級別:COLUMN. 別名:ADD COLUMN
          :) alter table ttt add column col1 String;
        • ALTER DROP COLUMN. 級別:COLUMN. 別名:DROP COLUMN
          :) alter table ttt drop column col1;
        • ALTER MODIFY COLUMN. 級別:COLUMN. 別名:MODIFY COLUMN
          :) alter table ttt modify column col1 UInt16;
        • ALTER COMMENT COLUMN. 級別:COLUMN. 別名:COMMENT COLUMN
          :) alter table ttt comment column col1 'xxxx';
        • ALTER CLEAR COLUMN. 級別:COLUMN. 別名:CLEAR COLUMN
          :) alter table ttt clear column col1;
        • ALTER RENAME COLUMN. 級別:COLUMN. 別名:RENAME COLUMN
          :) alter table ttt rename column col1 to col2;
      • ALTER INDEX. 級別:GROUP. 別名:INDEX
        • ALTER ORDER BY. 級別:TABLE. 別名:ALTER MODIFY ORDER BY,MODIFY ORDER BY
          :) alter table ttt modify order by name;
        • ALTER ADD INDEX. 級別:TABLE. 別名:ADD INDEX
          :) alter table ttt add index idx_name(name) type minmax granularity 5;
        • ALTER DROP INDEX. 級別:TABLE. 別名:DROP INDEX
          :) alter table ttt drop index idx_name;
        • ALTER MATERIALIZE INDEX. 級別:TABLE. 別名:MATERIALIZE INDEX
        • ALTER CLEAR INDEX. 級別:TABLE. 別名:CLEAR INDEX
      • ALTER CONSTRAINT. 級別:GROUP. 別名:CONSTRAINTALTER TTL. 級別:TABLE. 別名:ALTER MODIFY TTL,MODIFY TTL
        • ALTER ADD CONSTRAINT. 級別:TABLE. 別名:ADD CONSTRAINT
        • ALTER DROP CONSTRAINT. 級別:TABLE. 別名:DROP CONSTRAINT
      • ALTER MATERIALIZE TTL. 級別:TABLE. 別名:MATERIALIZE TTL
      • ALTER SETTINGS. 級別:TABLE. 別名:ALTER SETTING,ALTER MODIFY SETTING,MODIFY SETTING
      • ALTER MOVE PARTITION. 級別:TABLE. 別名:ALTER MOVE PART,MOVE PARTITION,MOVE PART
      • ALTER FETCH PARTITION. 級別:TABLE. 別名:FETCH PARTITION
      • ALTER FREEZE PARTITION. 級別:TABLE. 別名:FREEZE PARTITION
    • ALTER VIEW級別:GROUP
      • ALTER VIEW REFRESH. 級別:VIEW. 別名:ALTER LIVE VIEW REFRESH,REFRESH VIEW
      • ALTER VIEW MODIFY QUERY. 級別:VIEW. 別名:ALTER TABLE MODIFY QUERY
    ALTER許可權包含所有其它ALTER *的許可權:
    :) GRANT ALTER  ON testdb.ttt TO zjy;

    該許可權允許zjy對 testdb.ttt表執行資料matution操作,許可權包括上面列出來的各個操作:DELETE、UPDATE、ADD/DROP COLUMN/INDEX、MODIFY、TTL等等。
    關於 ALTER 更多語法可以看手冊

  • CREATE
    允許執行 CREATE和ATTACH的許可權
    • CREATE. 級別:GROUP
      • CREATE DATABASE. 級別:DATABASE
      • CREATE TABLE. 級別:TABLE
      • CREATE VIEW. 級別:VIEW
      • CREATE DICTIONARY. 級別:DICTIONARY
      • CREATE TEMPORARY TABLE. 級別:GLOBAL
    CREATE許可權包含所有其它CREATE *的許可權:
    :) GRANT CREATE ON *.* TO zjy;

    該許可權允許使用者zjy建庫、建表、建檢視、字典、臨時表等。

  • DROP

    允許執行DROP和DETACH許可權:

    • DROP. 級別:
      • DROP DATABASE. 級別:DATABASE
      • DROP TABLE. 級別:TABLE
      • DROP VIEW. 級別:VIEW
      • DROP DICTIONARY. 級別:DICTIONARY
    :) GRANT DROP ON *.* TO zjy;

    該許可權允許使用者zjy刪庫、刪表、刪檢視、刪字典等。

  • TRUNCATE

    允許執行TRUNCATE許可權,許可權級別:TABLE.

    :) GRANT TRUNCATE ON *.* TO zjy;

    該許可權允許使用者zjy清空表。

  • OPTIMIZE

    允許執行OPTIMIZE TABLE許可權,許可權級別:TABLE.

    :) GRANT OPTIMIZE ON *.* TO zjy;

    該許可權允許使用者zjy optimize 表。

  • SHOW

    允許根據下面的許可權層級來執行SHOW,DESCRIBE,USE, 和EXISTS:

    • SHOW. 級別:GROUP
      • SHOW DATABASES. 級別:DATABASE. 允許執行SHOW DATABASES,SHOW CREATE DATABASE,USE <database>.
      • SHOW TABLES. 級別:TABLE. 允許執行SHOW TABLES,EXISTS <table>,CHECK <table>.
      • SHOW COLUMNS. 級別:COLUMN. 允許執行SHOW CREATE TABLE,DESCRIBE.
      • SHOW DICTIONARIES. 級別:DICTIONARY. 允許執行SHOW DICTIONARIES,SHOW CREATE DICTIONARY,EXISTS <dictionary>.
    :) GRANT SHOW ON *.* TO zjy;

    該許可權允許使用者zjy 執行show相關許可權,show users 許可權需要單獨定義。注意:當用戶對指定表,字典或資料庫有其它的許可權時,同時會授予SHOW許可權。

  • KILL QUERY

    允許根據下面的許可權層級來執行KILL,許可權級別:GLOBAL。

    :) GRANT KILL QUERY ON *.* TO zjy;

    該許可權允許使用者zjy 執行kill query相關許可權。

  • ACCESS MANAGEMENT
    允許執行管理使用者/角色和行規則的操作
    :) grant ACCESS MANAGEMENT on *.* to zjy;

    該許可權允許使用者zjy管理使用者許可權,包括:建立/刪除/修改 使用者、角色、行規則、熔斷規則、SETTING、SHOW 使用者相關等等。

  • SYSTEM
    允許根據下面的許可權層級來執行SYSTEM,改許可權包含服務的關閉、刷寫、過載等。
    • SYSTEM. 級別:GROUP
      • SYSTEM SHUTDOWN.級別:GLOBAL. 別名:SYSTEM KILL,SHUTDOWN
      • SYSTEM DROP CACHE. 別名:DROP CACHE
        • SYSTEM DROP DNS CACHE. 級別:GLOBAL. 別名:SYSTEM DROP DNS,DROP DNS CACHE,DROP DNS
        • SYSTEM DROP MARK CACHE. 級別:GLOBAL. 別名:SYSTEM DROP MARK,DROP MARK CACHE,DROP MARKS
        • SYSTEM DROP UNCOMPRESSED CACHE. 級別:GLOBAL. 別名:SYSTEM DROP UNCOMPRESSED,DROP UNCOMPRESSED CACHE,DROP UNCOMPRESSED
      • SYSTEM RELOAD. 級別:GROUP
        • SYSTEM RELOAD CONFIG. 級別:GLOBAL. 別名:RELOAD CONFIG
        • SYSTEM RELOAD DICTIONARY. 級別:GLOBAL. 別名:SYSTEM RELOAD DICTIONARIES,RELOAD DICTIONARY,RELOAD DICTIONARIES
        • SYSTEM RELOAD EMBEDDED DICTIONARIES. 級別:GLOBAL. 別名: RELOAD EMBEDDED DICTIONARIES
      • SYSTEM MERGES. 級別:TABLE. 別名:SYSTEM STOP MERGES,SYSTEM START MERGES,STOP MERGES,START MERGES
      • SYSTEM TTL MERGES. 級別:TABLE. 別名:SYSTEM STOP TTL MERGES,SYSTEM START TTL MERGES,STOP TTL MERGES,START TTL MERGES
      • SYSTEM FETCHES. 級別:TABLE. 別名:SYSTEM STOP FETCHES,SYSTEM START FETCHES,STOP FETCHES,START FETCHES
      • SYSTEM MOVES. 級別:TABLE. 別名:SYSTEM STOP MOVES,SYSTEM START MOVES,STOP MOVES,START MOVES
      • SYSTEM SENDS. 級別:GROUP. 別名:SYSTEM STOP SENDS,SYSTEM START SENDS,STOP SENDS,START SENDS
        • SYSTEM DISTRIBUTED SENDS. 級別:TABLE. 別名:SYSTEM STOP DISTRIBUTED SENDS,SYSTEM START DISTRIBUTED SENDS,STOP DISTRIBUTED SENDS,START DISTRIBUTED SENDS
        • SYSTEM REPLICATED SENDS. 級別:TABLE. 別名:SYSTEM STOP REPLICATED SENDS,SYSTEM START REPLICATED SENDS,STOP REPLICATED SENDS,START REPLICATED SENDS
      • SYSTEM REPLICATION QUEUES. 級別:TABLE. 別名:SYSTEM STOP REPLICATION QUEUES,SYSTEM START REPLICATION QUEUES,STOP REPLICATION QUEUES,START REPLICATION QUEUES
      • SYSTEM SYNC REPLICA. 級別:TABLE. 別名:SYNC REPLICA
      • SYSTEM RESTART REPLICA. 級別:TABLE. 別名:RESTART REPLICA
      • SYSTEM FLUSH. 級別:GROUP
        • SYSTEM FLUSH DISTRIBUTED. 級別:TABLE. 別名:FLUSH DISTRIBUTED
        • SYSTEM FLUSH LOGS. 級別:GLOBAL. 別名:FLUSH LOGS
    :) grant SYSTEM  on *.* to zjy;

    該許可權允許使用者zjy執行SYSTEM相關操作。

  • INTROSPECTION
  • SOURCES

    允許在table enginestable functions中使用外部資料來源。

    • SOURCES. 級別:GROUP
      • FILE. 級別:GLOBAL
      • URL. 級別:GLOBAL
      • REMOTE. 級別:GLOBAL
      • YSQL. 級別:GLOBAL
      • ODBC. 級別:GLOBAL
      • JDBC. 級別:GLOBAL
      • HDFS. 級別:GLOBAL
      • S3. 級別:GLOBAL
    :) grant sources  on *.* to zjy; 

    該許可權允許使用者zjy執行sources相關操作。

  • dictGet:別名:dictHas,dictGetHierarchy,dictIsIn,許可權級別:DICTIONARY
    :) grant dictGet  on *.* to zjy;
    允許使用者執行dictGet,dictHas,dictGetHierarchy,dictIsIn等函式
  • ALL

    給使用者或角色授予所有許可權

    :) grant ALL  on *.* to zjy;
  • NONE
    不授予任何許可權,類似於MySQL的USAGE。

    :) grant NONE  on *.* to zjy;
  • ADMIN OPTION

    :) grant xxx to zjy with admin option;

    允許使用者將他們的角色分配給其它使用者:把角色xxx分配給zjy,之後zjy使用者也可以分配xxx角色。

  • GRANT OPTION

    :) grant all on *.* to zjy with grant option;

    授予zjy 可以執行GRANT操作的許可權,可將自身的許可權對其他物件進行授權。

7.授權(Grants privileges)

  • 給ClickHouse的使用者或角色賦予許可權
  • 將角色分配給使用者或其他角色

取消許可權,使用REVOKE語句,檢視已授的許可權使用SHOW GRANTS

GRANT [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} TO {user | role | CURRENT_USER} [,...] [WITH GRANT OPTION]
  • privilege— 許可權型別
  • role— 角色
  • user— 使用者

WITH GRANT OPTION授予userrole執行GRANT操作的許可權,之後該使用者可將自身的許可權對其他物件進行授權。

GRANT [ON CLUSTER cluster_name] role [,...] TO {user | another_role | CURRENT_USER} [,...] [WITH ADMIN OPTION]
  • role— 角色
  • user— 使用者

WITH ADMIN OPTION子句向用戶或角色授予 ADMIN OPTION 特權。

使用GRANT賬號必須有GRANT OPTION的許可權。使用者只能將在自身許可權範圍內的許可權進行授權。如:管理員有權通過下面的語句給john賬號新增授權

GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION

john有權執行GRANT OPTION,他能給其它賬號進行和自己賬號許可權範圍相同的授權。可以使用*號代替表或庫名進行授權操作。同樣,可以忽略庫名,許可權將指向當前的資料庫。

可以一次給多個賬號進行多種授權操作:

 GRANT SELECT,INSERT ON *.* TO john,robin;

允許johnrobin賬號對任意資料庫的任意表執行INSERTSELECT操作。訪問systen資料庫總是被允許的。

8.撤權(revoke privileges)

  • 取消使用者的許可權
    REVOKE [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} FROM {user | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user | CURRENT_USER} [,...]

    eg:

    :) revoke alter on *.* from zjy;

    說明:移除使用者zjy 的alter許可權。

    :) GRANT SELECT ON accounts.staff TO mira;
    :) REVOKE SELECT(wage) ON accounts.staff FROM mira;

    說明:授權mira賬號能查詢accounts.staff表的所有列,除了wage這一列。

  • 取消使用者的角色
    REVOKE [ON CLUSTER cluster_name] [ADMIN OPTION FOR] role [,...] FROM {user | role | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user_name | role_name | CURRENT_USER} [,...]

    eg:

    :) revoke xxx from zjy;

    移除使用者zjy上角色xxx的許可權。

9. 修改許可權(ALTER)

  • ALTER USER:修改使用者
    ALTER USER [IF EXISTS] name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1] 
            [, name2 [ON CLUSTER cluster_name2] [RENAME TO new_name2] ...]
        [NOT IDENTIFIED | IDENTIFIED {[WITH {no_password | plaintext_password | sha256_password | sha256_hash | double_sha1_password | double_sha1_hash}] BY {'password' | 'hash'}} | {WITH ldap SERVER 'server_name'} | {WITH kerberos [REALM 'realm']}]
        [[ADD | DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
        [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
        [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
        [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]

    eg:

    -- 改用名
    :) alter user zjy rename  to zjj;
    
    -- 改密碼
    :) alter user zjj IDENTIFIED with PLAINTEXT_PASSWORD by '123123';
    
    -- 新增白名單
    :) alter user zjj add host ip '10.2.2.2';
    
    -- 設定角色:
    :) alter user zjj default role all;
    
    -- 修改角色限制/profile
    :) alter user zjj SETTINGS PROFILE 'test';
  • ALTER ROLE:修改角色
    ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name]
        [RENAME TO new_name]
        [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]

    eg:

    -- 修改角色名
    :) alter role xyz rename to yyy;
    
    -- 修改角色限制/profile
    :) alter role yyy SETTINGS PROFILE 'test';
  • ALTER ROW POLICY:修改行策略
    ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table
        [RENAME TO new_name]
        [AS {PERMISSIVE | RESTRICTIVE}]
        [FOR SELECT]
        [USING {condition | NONE}][,...]
        [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    eg:
    -- 改名
    :) alter row policy pol1 on testdb.ttt rename to pol2;
    
    -- 修改
    :) alter row policy pol1 on testdb.ttt using id = 2;
  • ALTER QUOTA:修改配額熔斷規則
    ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name]
        [RENAME TO new_name]
        [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}]
        [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR}
            {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] |
            NO LIMITS | TRACKING ONLY} [,...]]
        [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]

    eg:

    -- 改名
    :) alter QUOTA qB rename to qq;
    
    -- 修改
    :) alter QUOTA qq FOR INTERVAL 30 minute MAX execution_time = 1, FOR INTERVAL 3 quarter MAX queries = 4321, errors = 100 TO zjj;
  • ALTER SETTINGS PROFILE:修改settings配置
    ALTER SETTINGS PROFILE [IF EXISTS] name [ON CLUSTER cluster_name]
        [RENAME TO new_name]
        [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...]

    eg:

    -- 改名
    :) ALTER SETTINGS PROFILE max_memory_usage_profile123 rename to max_memory_usage_profile;
    
    -- 修改
     :) ALTER SETTINGS PROFILE max_memory_usage_profile SETTINGS max_memory_usage = 100000002 MIN 90000001 MAX 110000001;

10.刪除(drop)

  • DROP USER:刪除使用者
    :) DROP USER [IF EXISTS] name [,...] [ON CLUSTER cluster_name];
  • DROP ROLE:刪除角色,刪除的角色將從分配給它的所有實體中撤銷。

    :) DROP ROLE [IF EXISTS] name [,...] [ON CLUSTER cluster_name];
  • DROP ROW POLICY:刪除行策略,刪除的行策略從分配給它的所有實體中撤銷。

    :) DROP [ROW] POLICY [IF EXISTS] name [,...] ON [database.]table [,...] [ON CLUSTER cluster_name];
  • DROP QUOTA:刪除配額熔斷。 刪除的配額熔斷將從分配到它的所有實體中撤銷。

    :) DROP QUOTA [IF EXISTS] name [,...] [ON CLUSTER cluster_name];
  • DROP SETTINGS PROFILE:刪除profile檔案。 已刪除的檔案將從分配給它的所有實體中撤銷。

    :) DROP [SETTINGS] PROFILE [IF EXISTS] name [,...] [ON CLUSTER cluster_name];

11.檢視許可權(show)

  • SHOW GRANTS:顯示使用者的許可權
    :) SHOW GRANTS [FOR user]
  • SHOW CREATE USER:顯示建立使用者時用到的引數
    :) SHOW CREATE USER [name | CURRENT_USER]
  • SHOW CREATE ROLE:顯示建立角色時用到的引數
    :) SHOW CREATE ROLE name;
  • SHOW CREATE ROW POLICY:顯示建立行策略時用到的引數
    :) SHOW CREATE [ROW] POLICY name ON [database.]table;
  • SHOW CREATE QUOTA:顯示建立時配額熔斷時用到的引數

    :) SHOW CREATE QUOTA [name | CURRENT];
  • SHOW CREATE SETTINGS PROFILE:顯示建立settings時用到的引數

    :) SHOW CREATE [SETTINGS] PROFILE name;
  • SHOW USERS:返回使用者列表。檢視使用者引數,請參閱系統表system.users
    :) SHOW USERS;
  • SHOW ROLES:返回角色列表。檢視角色引數,請參閱系統表system.rolessystem.role-grants

    :) SHOW [CURRENT|ENABLED] ROLES;
  • SHOW PROFILES:返回配置檔案列表。要檢視配置引數,請參閱系統表settings_profiles

    :) SHOW [SETTINGS] PROFILES;
  • SHOW POLICIES:返回指定表的行策略列表。 要檢視使用者帳戶引數,請參閱系統表system.row_policies

    :) SHOW [ROW] POLICIES [ON [db.]table];
  • SHOW QUOTAS:返回配額列表。 要檢視配額引數,請參閱系統表system.quotas

    :) SHOW QUOTAS;
  • SHOW QUOTA:返回所有使用者或當前使用者的配額。 要檢視其他引數,請參閱系統表system.quotas_usagesystem.quota_usage

    :) SHOW [CURRENT] QUOTA;
  • SHOW ACCESS:顯示目前所有的usersrolesprofilesgrants資訊。

    :) SHOW ACCESS;
  • SHOW SETTINGS:顯示系統設定的列表。 從system.settings表中選擇資料。

    :) SHOW [CHANGED] SETTINGS LIKE|ILIKE <name>;

    LIKE | ILIKE允許為設定名稱指定匹配模式。 可以包含諸如 % 或 _ 之類的全域性變數。
    LIKE:區分大小寫,
    ILIKE:不區分大小寫。
    CHANGED:查詢僅返回從預設值更改的設定。

    eg:

    -- 使用 LIKE 子句查詢:
    :) SHOW SETTINGS LIKE 'send_timeout';
    
    -- 使用 ILIKE 子句查詢:
    :) SHOW SETTINGS ILIKE '%CONNECT_timeout%';
    
    -- 使用 CHANGED 子句查詢:
    :) SHOW CHANGED SETTINGS ILIKE '%MEMORY%'
  • SHOW CLUSTER(s):返回叢集列表。 所有可用的叢集都列在system.clusters 表中

    -- 指定檢視一個叢集
    :) SHOW CLUSTER '<name>';
    
    -- 模糊匹配叢集
    :) SHOW CLUSTERS [LIKE|NOT LIKE '<pattern>'] [LIMIT <N>];
    
    -- 檢視所有叢集
    :) SHOW CLUSTERS;

到此,訪問許可權和賬戶管理的介紹已經結束,包括了配置檔案和SQL方式的設定,從使用者建立/修改/刪除、角色建立/修改/刪除、許可權建立/撤等等,更多的資訊資訊可以見官網說明

實戰

前提條件:因為是通過SQL-driven來進行賬號操作的,在ClickHouse安裝好之後,會有個預設賬戶default,在該使用者下面開access_management引數即可。開啟引數:

    <users>

        <default>
            <password>123456</password>
            <networks>
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
            <access_management>1</access_management>
        </default>

    </users>

之後通過default使用者進行SQL-driven的賬號管理操作。

1. 建立賬號

  • 管理賬號
    -- 建立賬號
    :) create user dba host ip '127.0.0.1' identified with sha256_password by '123456';
    
    -- 授權,all
    :) grant all on *.* to dba with grant option;
  • 普通業務讀寫賬號
    -- 建立賬號
    :) create user app host ip '127.0.0.1' identified with sha256_password by '123456';
    
    -- 授權,增刪改查許可權
    :) grant select,insert,alter delete,alter update on testdb.* to app;
  • 只讀賬號
    -- 建立賬號
    :) create user ro host ip '127.0.0.1' identified with sha256_password by '123456';
    
    -- 授權,增刪改查許可權
    :) grant select on testdb.* to ro;

更多的語法見上面的CREATE USER。

2. 建立Role

  • 管理Role
    -- 建立Role
    :) CREATE ROLE DBA;
    
    -- 授權管理
    :) GRANT ALL ON *.* TO DBA with grant option;
    
    -- 給使用者授權角色
    :) GRANT DBA TO dba1;
  • 讀寫Role
    -- 建立Role
    :) CREATE ROLE WRITABLE;
    
    -- 授權增刪改查
    :) GRANT select,insert,alter delete,alter update ON *.* TO WRITABLE;
    
    -- 給使用者授權角色
    :) GRANT WRITABLE TO rw;
  • 只讀Role
    -- 建立Role
    :) CREATE ROLE READONLY;
    
    -- 授權增刪改查
    :) GRANT select ON *.* TO READONLY;
    
    -- 給使用者授權角色
    :) GRANT READONLY TO ro;

更多的語法見上面的CREATE ROLE。

3.建立行策略

用於確定使用者可以從表中讀取哪些行的過濾器,對應配置問了裡的filter引數。注意:行策略僅對具有隻讀訪問許可權的使用者有意義。

-- 建立行策略
:) CREATE ROW POLICY pol1 ON testdb.ttt USING b=1 TO app1;

-- 建立使用者,該使用者需要有select許可權,才能應用
:) create user app1 host ip '127.0.0.1' identified with sha256_password by '123456'; 

-- 行策略應用,該策略只能訪問x2表id大於5的資料
:) CREATE ROW POLICY pol1 ON testdb.x2 USING id>5 TO app1;

更多的語法見上面的 CREATE ROW POLICY。

4. 建立QUOTA
分配給使用者或角色的配額熔斷策略,限制使用者的使用資源。

-- 建立quota
:) CREATE QUOTA qA FOR INTERVAL 5 minute MAX queries = 10 TO app1;

限制使用者app1,5分鐘之內最多執行次數,超過則報錯:

Code: 201. DB::Exception: Received from localhost:9010. DB::Exception: Quota for user `app1` for 300s has been exceeded: queries = 11/10. Interval will end at 2021-07-01 00:20:00. Name of quota template: `qA`.

更多的語法見上面的 CREATE QUOTA。

5.建立Profile

建立可分配給使用者或角色的的配置檔案。

-- 限制使用者app的最大使用記憶體。
:) CREATE SETTINGS PROFILE max_memory_usage_profile SETTINGS max_memory_usage = 100000001 MIN 90000000 MAX 110000000 TO app;

更多的語法見上面的 CREATESETTINGS PROFILE。到此,正常的使用者許可權設定已經完成。

總結

從上面看到,通過SQL-driven來設定使用者許可權和管理比修改配置檔案要方便很多,官方也推薦使用該方式進行使用者許可權管理。通過該方式配置的使用者都是以檔案形式儲存在access目錄中,該目錄的位置是由引數local_directory控制:

        <local_directory>
            <!-- Path to folder where users created by SQL commands are stored. -->
            <!-- <path>/var/lib/clickhouse/access/</path> -->
            <path>/ccdata/clickhouse/access/</path>
        </local_directory>

注意,如果把該目錄的檔案刪除,則會讓這些使用者角色全部失效。