GrantForge

    Базы данных / Документные

    Агент MongoDB

    Запуск агента MongoDB рядом с развёртыванием, чтобы превращать политики GrantForge в собственные роли MongoDB, заменять привилегии роли за один шаг, читать, что дают встроенные и пользовательские роли вне GrantForge, и сообщать о доступе из журнала аудита или профилировщика.

    Агент MongoDB — это сервис рядом с развёртыванием. Он поддерживает собственное управление доступом MongoDB в соответствии с подписанными политиками сервиса данных mongodb: одна роль на пользователя, содержащая ровно то, что ему дают политики. Затем MongoDB сам проверяет каждую команду, а агент не стоит на пути ни одного клиента. Дистрибутив поставляет его как исполняемый JAR agents/mongodb/grantforge-agent-mongodb-<version>.jar; нужна Java 17 или новее.

    Интеграционные тесты Testcontainers в репозитории запускают агента и поставляемый JAR на наборах реплик MongoDB 6.0, 7.0, 8.0 и 9.0 и шардированном кластере 9.0 и читают журнал аудита Percona Server for MongoDB 7.0 и 8.0. Это не сертифицирует все остальные версии; агент отклоняет развёртывания старше 6.0. О сервисном плагине см. MongoDB.

    Как это работает

    • Одна роль на пользователя содержит то, что даёт GrantForge. Для каждого пользователя, которому политики что-то дают, агент поддерживает в admin роль с его именем, grantforge_alice для alice, и выдаёт её каждому пользователю MongoDB с этим именем, например alice@admin и alice@sales. rolesInfo показывает, что GrantForge даёт alice. Другие роли агент не меняет.
    • Изменение происходит за один шаг. updateRole заменяет привилегии роли разом, так что у пользователя никогда не бывает одновременно старых и новых или ни тех, ни других.
    • Целые базы данных там, где ниже ничего не решается иначе. Тип доступа, который политика разрешает на всю базу данных и который ни одна политика не может отнять ниже, выдаётся на базу, так что коллекции, созданные позже, получают его сразу. Иначе он выдаётся по коллекциям, а новые охватываются при следующей синхронизации.
    • Никогда больше, чем разрешают политики. Привилегия MongoDB на удаление базы данных — это привилегия на удаление каждой её коллекции. Агент выдаёт её только там, где политики дают и это; иначе не выдаёт и один раз записывает в журнал, какой пользователь чего не может и почему.
    • Политики текущего момента. Каждая синхронизация планирует по политикам, действующим в этот момент, так что сроки действия начинаются и заканчиваются вовремя, и по пользователям, базам данных и коллекциям, которые есть в MongoDB, так что новые охватываются при следующей синхронизации.
    • Роли MongoDB — это группы. Политика для группы применяется к пользователям с ролью MongoDB с таким именем, а также к группам, в которые их помещает GrantForge.
    • Ручные изменения отменяются. При каждой синхронизации агент сравнивает свои роли с планами и исправляет привилегии, изменённые вручную, роли, которые заставили их наследовать, выдачу роли кому-то другому и роли, которые никому не нужны. Если ничего не изменилось, он ничего не отправляет.
    • Роли вне GrantForge читаются на предмет того, что они дают. MongoDB суммирует то, что дают все роли пользователя, поэтому агент не может отнять то, что у пользователя есть через другую роль. MongoDB сообщает, что даёт каждая роль, включая встроенные и унаследованные, поэтому агент по одному разу предупреждает о роли вроде readWrite@hr, дающей то, что запрещает политика, называя пользователя, доступ и политику. Он также предупреждает о пользователях, которые могут администрировать пользователей и так выдать себе что угодно, о пользователях с root или любым действием на любом ресурсе и о сервере, который вообще не проверяет авторизацию.
    • Доступ берётся из журнала аудита или профилировщика. См. раздел «Сообщения о доступе» ниже. Каждое событие сообщает, решил ли GrantForge, то есть решают ли политики так же, как MongoDB, или команду разрешила внешняя роль. Об агрегации сообщается для каждой коллекции, которую читают её стадии $lookup, $graphLookup и $unionWith и записывают $out и $merge. События называют команду и её пространство имён, но никогда её аргументы, которые могут содержать документы и пароли.

    Развёртывание

    1. Добавьте сервис данных mongodb и настройте его политики. Откройте Права доступа к данным → Агенты, выберите сервис и выпустите токен агента. Он показывается только один раз; сохраните его в файл, который может читать только учётная запись агента.

    2. Создайте пользователя MongoDB для агента. Он создаёт и меняет роли и читает пользователей и роли с помощью userAdminAnyDatabase; перечисляет коллекции с помощью роли, которая содержит только это; и читает параметры сервера и профилировщик с помощью clusterMonitor. userAdminAnyDatabase может выдать себе что угодно, поэтому защищайте этого пользователя как администратора. Имя роли для перечисления не должно начинаться с префикса ролей агента.

      const admin = db.getSiblingDB("admin");
      admin.createRole({ role: "agent_inventory", roles: [],
        privileges: [{ resource: { db: "", collection: "" }, actions: ["listCollections"] }] });
      admin.createUser({ user: "grantforge", pwd: passwordPrompt(),
        roles: ["userAdminAnyDatabase", "clusterMonitor", "agent_inventory"] });
    3. Чтобы сообщать о доступе, настройте один из источников из раздела «Сообщения о доступе» ниже.

    4. Напишите файл параметров, заменив примерные адреса, пути и имена:

      grantforge.server.url=https://grantforge.example.com
      grantforge.token.file=/etc/grantforge/mongodb-agent.token
      grantforge.instance=mongodb-agent-1
      grantforge.cache.dir=/var/lib/grantforge/mongodb-agent
      grantforge.mongodb.uri=mongodb://db1.internal:27017,db2.internal:27017/?replicaSet=rs0
      grantforge.mongodb.user=grantforge
      grantforge.mongodb.password.file=/etc/grantforge/mongodb-agent.password

      Эти пути находятся на машине агента, а каталог кэша должен быть доступен для записи. Файлы паролей читаются в UTF-8 с обрезкой пробелов.

    5. Запустите агент, например как службу systemd:

      java -jar agents/mongodb/grantforge-agent-mongodb-<version>.jar /etc/grantforge/mongodb-agent.properties

      Замените <version> версией дистрибутива. Параметры, переданные как java -Dgrantforge.…=… -jar …, переопределяют файл. По SIGTERM агент корректно останавливается и отправляет или откладывает ожидающие события; MongoDB сохраняет то, что получил.

    6. Перенос существующих привилегий в политики: роли, выданные вне GrantForge, продолжают действовать рядом с ролями агента. Создайте соответствующие политики, затем отзовите эти роли. Предупреждения агента указывают на те, что дают запрещённое политикой.

    Параметр Назначение
    grantforge.server.url, grantforge.token.file, grantforge.instance, grantforge.cache.dir Обязательно: сервер GrantForge, файл токена агента, имя этого агента и доступный для записи каталог для подписанного снимка, отложенных событий и позиции чтения журнала аудита
    grantforge.signing.key.file Необязательный файл, закрепляющий ключ подписи снимков; скопируйте открытый ключ X.509 Ed25519 в Base64 со страницы «Агенты». Если не задан, ключ берётся с сервера при первом обращении
    grantforge.mongodb.uri Обязательно: строка подключения без учётных данных
    grantforge.mongodb.auth.mechanism SCRAM-SHA-256 (по умолчанию), SCRAM-SHA-1, MONGODB-X509, PLAIN или GSSAPI
    grantforge.mongodb.user, grantforge.mongodb.password.file, grantforge.mongodb.auth.source Пользователь агента, при GSSAPI его принципал, при MONGODB-X509 необязателен; его пароль; для SCRAM — база данных, в которой он определён, по умолчанию admin
    grantforge.mongodb.tls.ca.file, grantforge.mongodb.tls.certificate.key.file, grantforge.mongodb.tls.certificate.key.password.file При tls=true в строке подключения: PEM-сертификаты ЦС для проверки серверов, пустое значение — то, чему доверяет Java; один PEM-файл с клиентским сертификатом и его ключом; пароль зашифрованного ключа
    grantforge.mongodb.kerberos.keytab, grantforge.mongodb.kerberos.service.name GSSAPI: keytab принципала, иначе используется пароль, и имя службы принципала серверов, по умолчанию mongodb. Область берётся из krb5.conf машины
    grantforge.mongodb.timeout.ms Сколько могут занимать поиск сервера, подключение и одна команда, по умолчанию 30000, в диапазоне 1..600000 миллисекунд
    grantforge.mongodb.role.prefix С чего начинаются имена ролей агента, по умолчанию grantforge_. Буквы, цифры и подчёркивания, заканчивается подчёркиванием, не более 32 символов. Любая роль в admin, имя которой начинается так, принадлежит агенту
    grantforge.mongodb.unmanaged.users Пользователи, которых агент не трогает, через запятую, например служебные учётные записи. Он никогда не трогает собственного пользователя и пользователей с root, __system или любым действием на любом ресурсе
    grantforge.mongodb.databases Базы данных, в которых агент выдаёт по коллекциям, через запятую, пусто — все. Остальные получают только то, что можно выдать целиком, чтобы база с очень большим числом коллекций не перечислялась при каждой синхронизации
    grantforge.mongodb.audit.files Файлы журнала аудита для чтения, через запятую. Пустое значение читает профилировщик
    grantforge.sync.interval.ms Как часто агент приводит MongoDB в соответствие, по умолчанию 10000, диапазон 1000..3600000 миллисекунд
    grantforge.audit.log По умолчанию true. false не читает и не сообщает о доступе
    grantforge.audit.log.delay.ms, grantforge.audit.log.interval.ms, grantforge.audit.log.batch На сколько отставать от текущего момента при чтении профилировщика (по умолчанию 2000), как часто читать доступ (по умолчанию 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 — отправлять каждое

    Сообщения о доступе

    Источник Где Что сообщает Как включить
    Журнал аудита MongoDB Enterprise и Percona Server for MongoDB Что разрешено и что отклонено на каждом члене, файл которого может прочитать агент Запустите mongod с --auditDestination file --auditFormat JSON --auditPath <path> и --setParameter auditAuthorizationSuccess=true и укажите файлы в grantforge.mongodb.audit.files
    Профилировщик Все редакции Что выполнялось на члене, с которым общается агент, — первичном в наборе реплик; отказов нет db.setProfilingLevel(2) в каждой базе данных, о которой нужно сообщать. Это нагружает сервер, поэтому агент никогда не включает его сам, а system.profile — небольшая ограниченная коллекция

    Журнал аудита читается из файлов, поэтому запускайте агента на узле или дайте ему каталог, в котором они собираются. Тесты читают журнал аудита Percona Server, имеющий формат MongoDB Enterprise. У mongos нет профилировщика, поэтому шардированный кластер сообщает о доступе только из журнала аудита.

    Команда Событие доступа
    find, aggregate, count, distinct, listIndexes read для каждой прочитанной коллекции
    aggregate, начинающаяся с $changeStream change_stream
    insert, update, delete, findAndModify, bulkWrite insert, update или remove для каждой записанной коллекции; при запросе также bypass_validation
    createIndexes, dropIndexes create_index, drop_index
    collMod, validate, convertToCapped alter
    drop, create, dropDatabase drop, create, drop_database
    listDatabases; serverStatus, top, replSetGetStatus, connPoolStats, hostInfo, currentOp list_databases; monitor

    MongoDB отклоняет команду целиком, не говоря, какая из её коллекций стала причиной, поэтому об отказе сообщается для тех, которые запрещают политики, или для первой, если они не запрещают ни одной.

    Пользователи, группы и роли

    Политики называют пользователей MongoDB по имени пользователя. Имя, определённое в нескольких базах данных, — это один пользователь, и роль агента выдаётся всем им. Группы — это роли MongoDB пользователя и группы, в которые его помещает GrantForge. Роли — это роли, которые GrantForge даёт пользователю.

    Решения и ограничения

    • Без снимка агент ничего не меняет. Токен, привязанный к неиспользуемому сервису или к сервису не типа mongodb, ничего не выдаёт: агент удаляет свои роли, а собственные роли MongoDB остаются.
    • Пока агент не работает, MongoDB сохраняет полученное последним, а изменения политик ждут. Изменение доходит до MongoDB в пределах интервалов обновления и синхронизации; mongos применяет его, когда истечёт его кэш пользователей, по умолчанию в течение 30 секунд (userCacheInvalidationIntervalSecs).
    • Привилегии MongoDB точно называют базы данных и коллекции, поэтому подстановочный знак в политике выдаётся для того, что существует. База данных существует, когда в ней есть коллекция: до этого create на базу, названную в политике, выдавать не на что.
    • Пользователи, нигде не определённые в MongoDB, например те, кого авторизация LDAP сама сопоставляет с ролями, не видны, и агент не поддерживает для них ролей.
    • Привилегия на всю базу данных охватывает её коллекции, но не коллекции system., а собственные базы MongoDB остаются за MongoDB.
    • Переименование коллекций и прочие административные действия MongoDB не являются типами доступа: они остаются за ролями вне GrantForge.
    • MongoDB не фильтрует строки и не маскирует поля по ролям; представление даёт ограниченное чтение.

    Связанные руководства

    Редактировать эту страницу на GitHub