Авторизация
Система управления доступом к базе данных ADQM, основанная на концепции Role Based Access Control (RBAC), включает следующие объекты:
Создавать и настраивать эти объекты можно через SQL-запросы (рекомендуется) или конфигурационные файлы users.xml и config.xml. В данной статье описывается SQL-ориентированное управление доступом — приводится базовый синтаксис и примеры запросов для создания пользователей ADQM и ролей с определенными разрешениями и ограничениями на работу с базами данных, таблицами, столбцами и строками.
Чтобы воспроизвести приведенные ниже примеры, создайте таблицу test_table
в текущей базе данных и новую базу данных test_database
:
CREATE TABLE test_table (x Int32, y String, z Int32) ENGINE = MergeTree ORDER BY x;
CREATE DATABASE test_database;
Настройка авторизации для нового кластера
Чтобы режим управления доступом через SQL-запросы был включен, значение параметра access_management для пользователя должно быть установлено в 1
в файле users.xml.
При создании нового кластера ADQM по умолчанию предоставляется аккаунт пользователя default
без пароля, у которого активирована опция access_management
и есть все права на управление доступом. Этот аккаунт используется во всех случаях, когда имя пользователя не определено (например, при подключении к ADQM через клиента или выполнении распределенных запросов). Изменить настройки пользователя default
(в том числе назначить пароль для входа в ADQM) можно через интерфейс ADCM: ADQM cluster → Services → ADQMDB → Primary Configuration → Default user and policy settings.

Используйте аккаунт пользователя default
, чтобы настроить безопасный доступ к базе данных ADQM сразу после создания кластера. Для этого выполните следующие действия:
-
Подключитесь к ADQM как пользователь
default
(например, через клиент командной строки clickhouse-client). -
Создайте аккаунты пользователей (включая аккаунт администратора), необходимые для дальнейшей работы в ADQM.
-
Ограничьте разрешения для пользователя
default
и отключите для него SQL-ориентированное управление доступом (опция Access Management в интерфейсе ADCM).
Аккаунт пользователя
Аккаунт пользователя (user) — объект системы доступа, который позволяет авторизовать пользователя при его подключении к ADQM. Аккаунт пользователя содержит следующую информацию:
-
идентификационную информацию;
-
привилегии, определяющие типы запросов, которые пользователю разрешено выполнять;
-
хосты, с которых пользователь может подключаться к серверу ADQM;
-
назначенные пользователю роли и роли по умолчанию;
-
настройки, которые применяются при входе пользователя в систему.
Создание пользователя
Чтобы создать новый аккаунт пользователя в ADQM, используйте запрос CREATE USER
:
CREATE USER [IF NOT EXISTS | OR REPLACE] <user_name1> [ON CLUSTER <cluster_name1>]
[, <user_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 'ldap_server'} | {WITH ssl_certificate CN '<certificate_CN>'} | {WITH kerberos [REALM 'realm']}]
[HOST {LOCAL | NAME '<fqdn>' | REGEXP '<name_regexp>' | IP '<ip_address>' | LIKE '<pattern>'} [,...] | ANY | NONE]
[DEFAULT ROLE <role_name> [,...] | ALL | ALL EXCEPT <role_name> [,...] ]
[DEFAULT DATABASE <database_name> | NONE]
[GRANTEES {<user_name> | <role_name> | ANY | NONE} [,...] [EXCEPT {<user_name> | <role_name>} [,...]]]
[SETTINGS <setting_name> [= <value>] [MIN [=] <min_value>] [MAX [=] <max_value>] [READONLY | WRITABLE] | PROFILE '<profile_name>'] [,...];
ON CLUSTER |
По умолчанию создается пользователь, который может подключаться только к тому серверу, на котором был выполнен запрос |
NOT IDENTIFIED | IDENTIFIED |
Метод аутентификации пользователя: по паролю, через LDAP-сервер, по SSL-сертификату или по протоколу Kerberos |
HOST |
Хост, с которого можно устанавливать соединение с сервером ADQM |
DEFAULT ROLE |
Роль по умолчанию (активируются автоматически при входе пользователя в ADQM) |
DEFAULT DATABASE |
База данных, в которую будет входить пользователь при подключении к ADQM |
GRANTEES |
Пользователи или роли, которым разрешено получать привилегии от создаваемого пользователя при условии, что этому пользователю предоставлено соответствующее разрешение с использованием WITH GRANT OPTION |
SETTINGS |
Значения настроек и их ограничения, которые применяются при входе пользователя в систему. Помимо настроек, явно определенных через выражение |
Пример
Создайте пользователя john
, который может подключаться к любому серверу кластера default_cluster
, используя пароль qwerty
:
CREATE USER john ON CLUSTER default_cluster IDENTIFIED WITH sha256_password BY 'qwerty';
Изменение существующего пользователя
Изменить настройки существующего пользователя можно через запрос ALTER USER
:
ALTER USER [IF EXISTS] <user_name1> [ON CLUSTER <cluster_name1>] [RENAME TO <new_user_name1>]
[, <user_name2> [ON CLUSTER <cluster_name2>] [RENAME TO <new_user_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 'ldap_server'} | {WITH ssl_certificate CN '<certificate_CN>'} | {WITH kerberos [REALM 'realm']}]
[[ADD | DROP] HOST {LOCAL | NAME '<fqdn>' | REGEXP '<name_regexp>' | IP '<ip_address>' | LIKE '<pattern>'} [,...] | ANY | NONE]
[DEFAULT ROLE <role_name> [,...] | ALL | ALL EXCEPT <role_name> [,...] ]
[GRANTEES {<user_name> | <role_name> | ANY | NONE} [,...] [EXCEPT {<user_name> | <role_name>} [,...]]]
[SETTINGS <setting_name> [= <value>] [MIN [=] <min_value>] [MAX [=] <max_value>] [READONLY | WRITABLE] | PROFILE '<profile_name>'] [,...]
Пример
Следующий запрос дополнительно настраивает ранее созданного пользователя john
так, что теперь он может подключаться к серверам ADQM только с указанного IP-адреса:
ALTER USER john HOST IP '10.92.17.140';
Просмотр настроек пользователя
Посмотреть текущие настройки пользователя (параметры, указанные при создании пользователя, с учетом изменений, выполненных через ALTER USER
), можно с помощью запроса SHOW CREATE USER
:
SHOW CREATE USER [<user_name1> [, <user_name2> ...] | CURRENT_USER];
Пример
Выполните следующий запрос, чтобы посмотреть настройки пользователя john
:
SHOW CREATE USER john;
Вывод на экран:
--CREATE USER john--------------------------------------------------------- │ CREATE USER john IDENTIFIED WITH sha256_password HOST IP '10.92.17.140' │ ---------------------------------------------------------------------------
Привилегии пользователя
Чтобы определить права доступа пользователя к объектам ADQM, нужно присвоить ему привилегии — разрешения на выполнение определенных типов запросов.
Предоставление привилегий пользователю
Назначить пользователю привилегии можно двумя способами:
-
присвоить роль — совокупность привилегий;
-
назначить привилегии напрямую через запрос GRANT:
GRANT [ON CLUSTER <cluster_name>] <privilege>[(<column_name> [,...])] [,...] ON {<db_name>.<table_name> | <db_name>.* | *.* | <table_name> | *} TO {<user_name> | CURRENT_USER} [,...] [WITH GRANT OPTION] [WITH REPLACE OPTION];
Аргументы и выражения<privilege>
Тип привилегии
<column_name>
Имя столбца, для которого разрешено выполнение запросов, определяемых привилегией
<db_name>.<table_name>
Имя базы данных и имя таблицы, определяющие область действия привилегии
<user_name>
Имя пользователя, которому назначается привилегия
WITH GRANT OPTION
Пользователю разрешается выполнять запрос
GRANT
, то есть он может передавать свои привилегии той же или меньшей области действия другим пользователям и ролям, указанным какGRANTEES
при выполнении запроса CREATE USER / ALTER USERWITH REPLACE OPTION
Все старые привилегии пользователя заменяются новыми привилегиями (если выражение не используется в запросе, добавляются новые привилегии)
Примеры:-
Выдайте пользователю
john
привилегию на выполнение запросовSELECT
для столбцовx
иy
таблицыtest_table
в текущей базе данных:GRANT SELECT(x,y) ON test_table TO john;
-
Создайте новый аккаунт пользователя
admin
и предоставьте ему полные права администратора:CREATE USER admin IDENTIFIED BY 'admin';
GRANT ALL ON *.* TO admin WITH GRANT OPTION;
-
Просмотр привилегий пользователя
Набор привилегий пользователя складывается из привилегий, назначенных ему напрямую, и привилегий, присвоенных через роли. Используйте запрос SHOW GRANTS, чтобы посмотреть список привилегий пользователя (если в запросе пользователь не указан, возвращается список привилегий текущего пользователя):
SHOW GRANTS [FOR <user_name>];
Пример запроса:
SHOW GRANTS FOR john;
Вывод на экран:
--GRANTS FOR john-------------------------------- │ GRANT SELECT(x,y) ON default.test_table TO john │ -------------------------------------------------
Отзыв привилегий пользователя
Чтобы отозвать привилегию, используйте запрос REVOKE
:
REVOKE [ON CLUSTER <cluster_name>] <privilege>[(<column_name> [,...])] [,...]
ON {<db_name>.<table_name> | <db_name>.* | *.* | <table_name> | *}
FROM {<user_name> | CURRENT_USER} [,...] | ALL | ALL EXCEPT {<user_name> | CURRENT_USER} [,...];
Пример запроса, который отзывает у пользователя john
привилегию на чтение данных из столбца y
таблицы test_table
:
REVOKE SELECT(y) ON test_table FROM john;
Роль
Роль (role) — набор привилегий, которые получает пользователь, если ему назначена эта роль.
Управление ролями
В следующей таблице перечислены запросы, с помощью которых можно управлять ролями ADQM.
Запрос | Описание | Синтаксис |
---|---|---|
CREATE ROLE |
Создает новую роль в ADQM |
|
ALTER ROLE |
Изменяет настройки существующей роли |
|
SHOW CREATE ROLE |
Выводит на экран параметры, использованные при создании роли (с учетом изменений, если выполнялся запрос |
|
DROP ROLE |
Удаляет роль. При удалении роль отзывается у всех объектов системы доступа, которым она присвоена |
|
Привилегии ролей
Чтобы определить привилегии, которые будет предоставлять роль при назначении пользователю, используйте запрос GRANT
:
GRANT [ON CLUSTER <cluster_name>] <privilege>[(<column_name> [,...])] [,...] ON {<db_name>.<table_name> | <db_name>.* | *.* | <table_name> | *}
TO <role_name> [,...] [WITH GRANT OPTION] [WITH REPLACE OPTION];
<privilege> |
Тип привилегии |
<column_name> |
Имя столбца, для которого разрешено выполнение запросов, определяемых привилегией |
<db_name>.<table_name> |
Имя базы данных и имя таблицы, определяющие область действия привилегии |
<role_name> |
Имя роли, которой назначается привилегия |
WITH GRANT OPTION |
Пользователю, которому будет назначена роль, разрешается выполнять запрос |
WITH REPLACE OPTION |
Все старые привилегии роли заменяются новыми привилегиями (если выражение не используется в запросе, добавляются новые привилегии) |
Пример
Создайте роль и назначьте ей привилегию на чтение всех таблиц базы данных test_database
:
CREATE ROLE reader;
GRANT SELECT ON test_database.* TO reader;
Назначение роли пользователю
Одному пользователю можно назначить несколько ролей. Роль также может быть присвоена другой роли. Назначать и отзывать роли можно с помощью следующих запросов:
Запрос | Описание | Синтаксис |
---|---|---|
GRANT |
Назначает роль пользователю или другой роли.
|
|
REVOKE |
Отзывает роль у пользователя или другой роли |
|
Пример
Назначьте роль reader
пользователю john
:
GRANT reader TO john;
Убедитесь, что к ранее назначенной привилегии пользователя добавилась роль reader
:
SHOW GRANTS FOR john;
Результат выполнения запроса:
--GRANTS FOR john-------------------------------- │ GRANT SELECT(x,y) ON default.test_table TO john │ │ GRANT reader TO john │ -------------------------------------------------
Применение роли пользователя
Пользователи могут применять (активировать) назначенные роли в произвольных комбинациях с помощью запросов SET ROLE
и SET DEFAULT ROLE
. Конечный объем доступных пользователю действий определяется комбинацией привилегий, назначенных аккаунту пользователя напрямую, и привилегий всех примененных ролей.
Запрос | Описание | Синтаксис |
---|---|---|
SET ROLE |
Активирует роль для текущего пользователя |
|
SET DEFAULT ROLE |
Устанавливает роль по умолчанию для пользователя. Роли по умолчанию активируются автоматически при входе пользователя в ADQM. Ролями по умолчанию могут быть установлены только ранее назначенные пользователю роли. Установить роль по умолчанию можно также с помощью выражения |
|
Пример
После того, как пользователю john
была назначена роль reader
(см. пример выше), он может применить эту роль и выполнять разрешенные ей запросы:
SET ROLE reader;
SELECT * FROM test_database.*;
Политика доступа к строкам
Политика доступа к строкам — фильтр для конкретной таблицы, определяющий, какие строки доступны пользователю или роли.
Создание политики доступа к строкам
Чтобы создать политику доступа к строкам, используйте запрос CREATE ROW POLICY
:
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] <policy_name1> [ON CLUSTER <cluster_name1>] ON [<db_name1>.]<table_name1>
[, <policy_name2> [ON CLUSTER <cluster_name2>] ON [<db_name2>.]<table_name2> ...]
[AS {PERMISSIVE | RESTRICTIVE}]
[FOR SELECT] USING <filter_condition>
[TO {<user_name> | <role_name> [,...] | ALL | ALL EXCEPT <user_name> | <role_name> [,...]}];
AS |
Выражение, которое определяет, как комбинировать политики, если одновременно активно более одной политики для одной и той же таблицы и одного и того же пользователя. Возможные значения:
Иными словами, строка таблицы будет доступна для пользователя, если выполняется условие Например, если заданы следующие политики, пользователь
|
USING |
Условие для фильтрации строк. Пользователь может видеть строку, если указанное условие, вычисленное для строки, возвращает ненулевой результат |
TO |
Пользователи и роли, для которых должна действовать политика |
Если для таблицы не указано ни одной политики доступа к строкам, любой пользователь может выполнить команду SELECT
и получить все строки таблицы. Если создать хотя бы одну политику для таблицы, то доступ к строкам будет управляться этой политикой для всех пользователей (в том числе тех, для которых политика явно не указана).
Например, если определена политика:
CREATE ROW POLICY policy_1 ON test_table USING x=1 TO mary, john;
то:
-
пользователи
mary
иjohn
смогут видеть только строки, для которых выполняется условиеx=1
; -
все остальные пользователи вообще не будут иметь доступ к строкам таблицы
test_table
.
Чтобы скорректировать это поведение и предоставить другим пользователям доступ ко всем строкам, необходимо настроить дополнительную политику для этих пользователей. Например, создайте следующую политику для пользователя admin
:
CREATE ROW POLICY allow_admin_filter ON test_table USING 1 TO admin;
Изменение политики доступа к строкам
Запрос ALTER ROW POLICY
позволяет изменить существующую политику доступа к строкам таблицы:
ALTER [ROW] POLICY [IF EXISTS] <policy_name1> [ON CLUSTER <cluster_name1>] ON [<db_name1>.]<table_name1> [RENAME TO <new_policy_name1>]
[, <policy_name2> [ON CLUSTER <cluster_name2>] ON [<db_name2>.]<table_name2> [RENAME TO <new_policy_name2>] ...]
[AS {PERMISSIVE | RESTRICTIVE}]
[FOR SELECT]
[USING {<filter_condition> | NONE}][,...]
[TO {<user_name> | <role_name> [,...] | ALL | ALL EXCEPT <user_name> | <role_name> [,...]}];
Профиль настроек
Профиль настроек — набор настроек с указанными значениями и/или ограничениями, который назначается пользователю (или роли) и применяется при входе пользователя в систему.
Создание профиля настроек
Выполните запрос CREATE SETTINGS PROFILE
, чтобы создать профиль настроек. Синтаксис запроса:
CREATE SETTINGS PROFILE [IF NOT EXISTS | OR REPLACE] <profile_name1> [ON CLUSTER <cluster_name1>]
[, <profile_name2> [ON CLUSTER <cluster_name2>] ...]
[SETTINGS <setting_name> [= <value>] [MIN [=] <min_value>] [MAX [=] <max_value>] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT '<profile_name>'] [,...]
[TO {<role_name> | <user_name> | CURRENT_USER} [,...] | ALL | ALL EXCEPT {<role_name> | <user_name> | CURRENT_USER} [,...]];
Пример
Создайте профиль настроек my_profile
, который содержит значение настройки max_memory_usage
и запрещает менять эту переменную, и присвойте его пользователю john
. Есть несколько способов это сделать.
-
Выполните запрос
CREATE SETTINGS PROFILE
, используя выражениеTO
, чтобы указать пользователя:CREATE SETTINGS PROFILE my_profile SETTINGS max_memory_usage = 100000000 READONLY TO john;
-
Создайте профиль настроек, а затем назначьте его пользователю с помощью выражения
SETTINGS PROFILE
в запросеCREATE USER
илиALTER USER
:CREATE SETTINGS PROFILE my_profile SETTINGS max_memory_usage = 100000000 READONLY;
ALTER USER john SETTINGS PROFILE my_profile;
-
Профиль настроек можно также назначить роли, которая в свою очередь присваивается пользователю:
ALTER ROLE reader SETTINGS PROFILE my_profile;
Изменение профиля настроек
При необходимости изменить существующий профиль настроек используйте запрос ALTER SETTINGS PROFILE
:
ALTER SETTINGS PROFILE [IF EXISTS] TO <profile_name1> [ON CLUSTER <cluster_name1>] [RENAME TO <new_profile_name1>]
[, <profile_name2> [ON CLUSTER <cluster_name2>] [RENAME TO <new_profile_name2>] ...]
[SETTINGS <setting_name> [= <value>] [MIN [=] <min_value>] [MAX [=] <max_value>] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT '<profile_name>'] [,...]
[TO {<role_name> | <user_name> | CURRENT_USER} [,...] | ALL | ALL EXCEPT {<role_name> | <user_name> | CURRENT_USER} [,...]];
Квота
Квота — набор параметров, для которых ведется подсчет значений или устанавливаются ограничивающие значения, которые не должны быть превышены за некоторый интервал времени.
Квота присваивается пользователю или роли и позволяет учитывать или ограничивать потребление ресурсов (например, количество обработанных запросов, строк и прочитанных байт) за определенный интервал времени для этого пользователя или роли:
-
Подсчет значений параметров за интервал времени. В течение указанного интервала времени соответствующие данные считаются после выполнения каждого запроса и выводятся в лог сервера. Когда интервал заканчивается, все накопленные значения сбрасываются, и для следующего интервала расчет квоты начинается заново.
-
Ограничение значений параметров за интервал времени. Если в течение указанного интервала времени значение параметра превысило заданное ограничение, выводится сообщение о том, значение какого параметра и на сколько превышено, и когда начнется новый интервал (когда можно будет снова выполнять запросы). В рамках одной квоты можно указать несколько интервалов с разными ограничениями.
При распределенной обработке запроса учитываются ресурсы, потраченные на всех удаленных серверах. Накопленные величины хранятся на сервере-инициаторе запроса (если пользователь зайдет на другой сервер — там квота будет действовать "с нуля").
Создание квоты
Используйте запрос CREATE QUOTA
, чтобы создать квоту и присвоить ее пользователю или роли:
CREATE QUOTA [IF NOT EXISTS | OR REPLACE] <quota_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} = <max_value> } [,...] |
NO LIMITS | TRACKING ONLY} [,...]]
[TO {<role_name> | <user_name> | CURRENT_USER} [,...] | ALL | ALL EXCEPT {<role_name> | <user_name> | CURRENT_USER} [,...]];
KEYED BY |
Ключ квоты, по которому определяется совместное использование квоты. Учет ресурсов для каждого значения ключа квоты ведется независимо. Иными словами, соединения с одинаковым ключом квоты совместно используют один и тот же объем ресурсов, для которого выделена одна и та же квота. Ключи |
FOR INTERVAL |
Интервал времени, для которого подсчитывается или ограничивается использование ресурсов.
|
TO |
Пользователи и роли, для которых выделяется квота |
Пример
Создайте квоту, ограничивающую максимальное количество запросов для пользователя john
— не более 10 запросов каждые 15 минут:
CREATE QUOTA my_quota FOR INTERVAL 15 minute MAX queries = 10 TO john;
Если пользователь выполнил 10 запросов до того, как истекли 15 минут с начала действия квоты, при попытке выполнить одиннадцатый запрос появится сообщение:
Code: 201. DB::Exception: Received from localhost:9000. DB::Exception: Quota for user `john` for 900s has been exceeded: queries = 11/10. Interval will end at 2023-02-08 07:15:00. Name of quota template: `my_quota`. (QUOTA_EXCEEDED)
Изменение квоты
Изменить настройки существующей квоты можно, выполнив запрос ALTER QUOTA
:
ALTER QUOTA [IF EXISTS] <quota_name> [ON CLUSTER <cluster_name>]
[RENAME TO <new_quota_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} = <max_value> } [,...] |
NO LIMITS | TRACKING ONLY} [,...]]
[TO {<role_name> | <user_name> | CURRENT_USER} [,...] | ALL | ALL EXCEPT {<role_name> | <user_name> | CURRENT_USER} [,...]];
Просмотр информации о квотах
-
Список имен всех квот. Выполните запрос
SHOW QUOTAS
, чтобы получить имена всех существующих квот:SHOW QUOTAS;
-
Текущие настройки квоты. Параметры квоты (с учетом всех изменений, если для квоты выполнялся запрос
ALTER QUOTA
) можно получить одним из следующих способов:-
с помощью запроса
SHOW CREATE QUOTA
:SHOW CREATE QUOTA [<quota_name> [, ...] | CURRENT];
-
из системной таблицы system.quotas:
SELECT * FROM system.quotas [WHERE name = '<quota_name>'] [FORMAT <format_name>];
-
-
Данные об использовании квоты. Узнать сколько ресурсов использовано и сколько осталось можно:
-
с помощью запроса
SHOW QUOTA
(использование квоты для всех пользователей или только для текущего пользователя):SHOW [CURRENT] QUOTA;
-
из системной таблицы system.quotas_usage (использование квоты всеми пользователями):
SELECT * FROM system.quotas_usage [WHERE quota_name = '<quota_name>'] [FORMAT <format_name>];
-
из системной таблицы system.quota_usage (использование квоты текущим пользователем):
SELECT * FROM system.quota_usage [WHERE quota_name = '<quota_name>'] [FORMAT <format_name>];
-