Агент Apache Doris — это сервис рядом с кластером. Он поддерживает собственный контроль доступа Doris в соответствии с подписанными политиками сервиса данных doris: одна роль на пользователя, которая содержит ровно то, что ему дают политики, вплоть до столбцов и групп нагрузки, и одна политика строк на каждый фильтр строк. Затем Doris сам проверяет каждую инструкцию, а агент никогда не стоит между клиентами и фронтендами. Дистрибутив поставляет его как исполняемый JAR agents/doris/grantforge-agent-doris-<version>.jar, которому нужна Java 17 или новее.
Интеграционные тесты Testcontainers в репозитории запускают агент и поставляемый JAR на Apache Doris 2.1, 3.1, 4.0 и 4.1. Это не означает сертификацию всех остальных версий; агент отклоняет кластеры старше 2.1. О сервисном плагине см. Apache Doris.
Как это работает
- Одна роль на пользователя содержит то, что даёт GrantForge. Для каждого пользователя, которому политики что-то дают, агент ведёт роль с его именем,
grantforge_aliceдляalice, с комментарием, называющим пользователя, и выдаёт её каждой учётной записи пользователя, например'alice'@'%'и'alice'@'10.%'.SHOW ROLESпоказывает, что GrantForge даётalice; агент не меняет других ролей и привилегий, которых не выдавал. - Базы данных и каталоги целиком, где ниже ничего не решается иначе. Чтение, загрузка и показ представлений, которые политика разрешает на всю базу данных или каталог и которые ни одна политика ниже не может отнять, выдаются на базу данных или каталог, поэтому созданные позже таблицы получают их сразу. Иначе они выдаются потаблично, а чтение — по столбцам. Изменение выдаётся потаблично, поскольку привилегия Doris на базу данных позволила бы и переименовать её.
- Никогда больше, чем разрешают политики. Привилегия Doris создавать базы данных в каталоге — это привилегия создавать таблицы во всех них, а привилегия удалять базу данных — удалять все её таблицы. Агент выдаёт каждую только там, где политики дают и более широкую привилегию; иначе он удерживает её и однократно записывает в журнал, какой пользователь что не может и почему.
- Группы нагрузки выдаются по имени. Политика на группы нагрузки даёт
USAGE_PRIVна каждую разрешённую ею группу, чтобы пользователь мог выполнять в ней запросы; группы, созданные позже, охватываются при следующей синхронизации. - Фильтры строк становятся политиками строк. Фильтр строк — это разрешающая (permissive) политика строк роли пользователя на таблице. Новый фильтр появляется раньше привилегий, которые он сужает; изменившийся фильтр заменяется за ограничивающей (restrictive) политикой, не показывающей строк, так что пользователь никогда не видит больше, чем показывает любой из двух фильтров. Каждый фильтр сначала выполняется на своей таблице; фильтр, который Doris не может там выполнить или отклоняет, например называющий столбец, которого в таблице нет, заменяется фильтром, не показывающим пользователю строк, и записывается в журнал.
- Политики текущего момента. Каждая синхронизация планирует по политикам в том виде, в каком они действуют в этот момент, поэтому сроки действия начинаются и заканчиваются вовремя, и по пользователям, каталогам, базам данных, таблицам и столбцам Doris, поэтому новые охватываются при следующей синхронизации.
- Роли Doris — это группы. Политика для группы действует для пользователей, у которых есть роль Doris с таким именем, вместе с группами, в которые их помещает GrantForge.
- Ручные изменения отменяются. При каждой синхронизации агент сравнивает привилегии своих ролей, как их показывает
SHOW ROLES, и свои политики строк с планами и восстанавливает различия. Doris показывает привилегии на столбцы только по пользователю, объединёнными по всем его привилегиям: агент выдаёт столбцы, названные в плане, там, где пользователь не может прочитать их все, и однократно отзывает остальные у своей роли; столбец, который остаётся читаемым, получен через привилегию вне GrantForge. Если ничего не изменилось, агент ничего не отправляет. - Привилегии вне GrantForge сообщаются. Doris складывает привилегии и объединяет разрешающие политики строк через OR, поэтому агент не может отнять то, что пользователь имеет напрямую или через другую роль. Он однократно предупреждает о каждой такой привилегии, привилегии на столбец или политике строк, которая даёт то, что запрещает политика, называя пользователя, привилегию и её источник, а также о пользователях с
ADMIN_PRIVилиNODE_PRIV, которых не ограничивает ни одна роль. - Обращения берутся из журнала аудита. Агент читает
__internal_schema.audit_log, который пишет каждый фронтенд, и сообщает каждую инструкцию как одно событие на каждую затронутую таблицу, базу данных или каталог; какие таблицы затронуты, он читает из самой инструкции разборщиком Doris из Druid, поскольку журнал их не называет. Отказ — это одно событие отказа для привилегии и объекта, названных в ошибке Doris. Каждое событие сообщает, решил ли это GrantForge, то есть совпадает ли решение политик с решением Doris, или разрешила привилегия вне GrantForge. Журнал читается с отставанием от текущего момента на интервал пакетной записи фронтендов,audit_plugin_max_batch_interval_sec, и ещё пять секунд.
| Инструкция | Событие доступа |
|---|---|
SELECT, читающая часть INSERT … SELECT |
select на каждой прочитанной таблице |
INSERT, UPDATE, DELETE, TRUNCATE |
load на записанной таблице |
ALTER TABLE, DROP TABLE, SHOW CREATE VIEW |
alter, drop, show_view на таблице |
CREATE TABLE, CREATE VIEW |
create на базе данных |
DROP DATABASE |
drop_database на базе данных |
CREATE DATABASE |
create_database на каталоге |
Развёртывание
-
Добавьте сервис данных
dorisи настройте его политики. Откройте Права доступа к данным → Агенты, выберите сервис и выпустите токен агента. Он показывается только один раз; сохраните его в файл, который может читать только учётная запись агента. -
Создайте пользователя Doris для агента. Он создаёт роли и политики строк, выдаёт то, что дают политики, и читает привилегии каждого пользователя и журнал аудита, что позволяет
ADMIN_PRIV:CREATE USER 'grantforge'@'%' IDENTIFIED BY '…'; GRANT ADMIN_PRIV ON *.*.* TO 'grantforge'@'%'; -
Чтобы сообщать об обращениях, включите журнал аудита Doris там, где он выключен, как в Doris 2.1:
SET GLOBAL enable_audit_plugin = true.audit_plugin_max_batch_interval_secкороче стандартных 60 секунд позволяет сообщать об обращениях быстрее. -
Напишите файл параметров, заменив примерные адреса, пути и имена:
grantforge.server.url=https://grantforge.example.com grantforge.token.file=/etc/grantforge/doris-agent.token grantforge.instance=doris-agent-1 grantforge.cache.dir=/var/lib/grantforge/doris-agent grantforge.doris.hosts=fe1.internal:9030,fe2.internal:9030 grantforge.doris.user=grantforge grantforge.doris.password.file=/etc/grantforge/doris-agent.passwordЭти пути находятся на машине агента, а каталог кэша должен быть доступен для записи. Файлы паролей читаются в UTF-8 с обрезкой пробелов.
-
Запустите агент, например как службу systemd:
java -jar agents/doris/grantforge-agent-doris-<version>.jar /etc/grantforge/doris-agent.propertiesЗамените
<version>версией дистрибутива. Параметры, переданные какjava -Dgrantforge.…=… -jar …, переопределяют файл. По SIGTERM агент корректно останавливается и отправляет или откладывает ожидающие события; Doris сохраняет то, что получил. -
Перенесите существующие привилегии в политики: привилегии, выданные вне GrantForge, продолжают действовать наряду с ролями агента. Создайте соответствующие политики, затем отзовите эти привилегии; предупреждения агента называют те, что дают то, что запрещает политика.
| Параметр | Назначение |
|---|---|
grantforge.server.url, grantforge.token.file, grantforge.instance, grantforge.cache.dir |
Обязательно: сервер GrantForge, файл токена агента, имя этого агента и доступный для записи каталог для подписанного снимка, отложенных событий и позиции чтения журнала аудита |
grantforge.signing.key.file |
Необязательный файл, закрепляющий ключ подписи снимков; скопируйте открытый ключ X.509 Ed25519 в Base64 со страницы «Агенты». Если не задан, ключ берётся с сервера при первом обращении |
grantforge.doris.hosts, grantforge.doris.user |
Обязательно: адреса протокола MySQL фронтендов, по очереди, если один недоступен, порт 9030, если не указан, и пользователь Doris для агента |
grantforge.doris.password.file |
Пароль пользователя; если не задан, агент входит без пароля |
grantforge.doris.ssl.mode, grantforge.doris.tls.ca |
disable (по умолчанию), trust, verify-ca или verify-full — для фронтендов, которые предлагают TLS; и PEM-сертификат CA, которым они проверяются, пусто — доверие тому, чему доверяет Java |
grantforge.doris.timeout.ms |
Сколько могут занимать подключение и инструкция, по умолчанию 30000, диапазон 1..600000 миллисекунд |
grantforge.doris.role.prefix |
Начало имён ролей агента, по умолчанию grantforge_; буквы, цифры и подчёркивания, оканчивается подчёркиванием, не более 32 символов. Агенту принадлежат все роли и политики строк, имена которых начинаются с него |
grantforge.doris.unmanaged.users |
Пользователи, которых агент не трогает, через запятую, например сервисные учётные записи; своего пользователя, root, admin и пользователей с ADMIN_PRIV или NODE_PRIV он не трогает никогда |
grantforge.doris.catalogs |
Каталоги, в которых агент выдаёт привилегии по базам данных, таблицам и столбцам, через запятую; пусто — все. Остальные получают только то, что можно выдать на них целиком, так что внешний каталог со множеством таблиц не нужно перечислять при каждой синхронизации |
grantforge.sync.interval.ms |
Как часто агент приводит Doris в соответствие, по умолчанию 10000, диапазон 1000..3600000 миллисекунд |
grantforge.audit.log |
По умолчанию true; false — не читать журнал аудита и не сообщать об обращениях |
grantforge.audit.log.delay.ms, grantforge.audit.log.interval.ms, grantforge.audit.log.batch |
Отставание чтения журнала от текущего момента, по умолчанию интервал пакетной записи кластера и пять секунд; как часто он читается, по умолчанию 5000 миллисекунд; и наибольшее число записей за одно чтение, по умолчанию 1000 |
grantforge.connect.timeout.ms, grantforge.read.timeout.ms |
Тайм-ауты подключения и чтения GrantForge, по умолчанию 5000 / 8000 миллисекунд |
grantforge.refresh.interval.ms |
Как часто агент запрашивает новые политики, по умолчанию 30000, не менее 1000 миллисекунд |
grantforge.audit.batch.size, grantforge.audit.queue.capacity, grantforge.audit.flush.interval.ms, grantforge.audit.spool.limit.bytes |
События доступа: размер пакета (по умолчанию 500), размер очереди (по умолчанию 10000), интервал отправки (по умолчанию 5000 миллисекунд) и предел отложенного на диске (по умолчанию 64 МиБ) |
grantforge.audit.fold.window.ms |
Сколько времени одинаковые разрешённые обращения сворачиваются в одно событие, по умолчанию 10000, до 3600000 миллисекунд; 0 — отправлять каждое |
Пользователи, группы и роли
Политики называют пользователей Doris по их именам; имя пользователя с несколькими хостами — один пользователь, и роль агента получает каждая его учётная запись. Группы — это роли Doris пользователя вместе с группами, в которые его помещает GrantForge; роли — это роли, которые GrantForge даёт пользователю.
Решения и ограничения
- Без снимка агент ничего не меняет. Неиспользуемый сервис или токен, привязанный к сервису с типом не
doris, ничего не выдают: агент удаляет свои роли и политики строк, и действуют собственные привилегии Doris. - Пока агент не работает, Doris сохраняет то, что получил последним; изменения политик ждут агента. Изменение доходит до Doris в пределах интервала обновления и интервала синхронизации.
- Таблицы, созданные в базе данных, где агент выдаёт привилегии потаблично, и базы данных каталога, где он выдаёт их по базам, получают привилегии при следующей синхронизации.
- Политики строк Doris не могут ограничить
rootиadmin. Пользователь, для которого Doris не показывает ни одной политики строк, видит все строки таблицы; разрешающие политики строк, созданные вне GrantForge для того же пользователя, расширяют то, что показывает его фильтр. - Doris проверяет
USAGE_PRIVна группу нагрузки, когда запрос выполняется на бэкендах; запрос, на который фронтенд отвечает сам, например константа или кэшированный результат, выполняется без проверки. Каждый пользователь может пользоваться группойnormal, поскольку Doris даёт её всем. - Пользователи, для которых агент ведёт роли, должны существовать в Doris; пользователи, входящие через LDAP без собственного пользователя Doris, роли не получают.
- Doris маскирует значения только через Apache Ranger, поэтому политики не могут маскировать значения.
