Безопасность: аутентификация, RBAC, TLS

Рейтинг: 52.3% · 11 голосов
Исчерпывающий курс по Tarantool 3.x: модель данных, движки memtx и vinyl, Lua и файберы, транзакции и MVCC, SQL, конфигурация (box.cfg и декларативная 3.x), репликация и Raft, шардирование vshard, эксплуатация, безопасность. 47 уроков со схемами.
Ответить
Аватара пользователя
denis_tnt
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Безопасность: аутентификация, RBAC, TLS

Сообщение denis_tnt »

Оглавление курса (47)
  1. Что такое Tarantool: in-memory СУБД и сервер приложений
  2. Архитектура изнутри: процесс, потоки, event-loop
  3. Установка и первый запуск: tt CLI, пакеты, Docker
  4. Интерактив: консоль, admin-консоль, первые команды
  5. Спейсы и кортежи: форматы, типы данных
  6. Типы индексов и их применимость
  7. Движки хранения: memtx vs vinyl
  8. DDL: схема, создание спейсов и индексов, миграции
  9. DML и выборки: insert/update/upsert, итераторы
  10. Персистентность: WAL, снапшоты, recovery
  11. Внутренности memtx: аллокаторы slab/arena, память
  12. Внутренности vinyl: LSM, компакция, тюнинг
  13. Lua и LuaJIT в Tarantool: box, модули, rocks
  14. Файберы: кооперативная многозадачность, каналы
  15. Транзакции: ACID, изоляция, MVCC
  16. Хранимые процедуры, модули, организация приложения
  17. net.box: удалённые вызовы, async
  18. Пулы соединений, балансировка, реконнект
  19. Ошибки и диагностика: box.error, pcall
  20. Типы и сериализация: MsgPack, decimal, datetime, uuid
  21. SQL в Tarantool: возможности и связь с box
  22. SQL: таблицы, JOIN, подзапросы, представления
  23. SQL: подготовленные выражения, транзакции, Lua-интероп
  24. Классическая конфигурация box.cfg (legacy 1.x/2.x)
  25. Декларативная конфигурация 3.x: config.yaml, иерархия
  26. Роли и приложения в 3.x
  27. Централизованная конфигурация: etcd / config storage
  28. tt CLI глубоко: разработка, сборка, запуск
  29. Cartridge (официальный legacy) и миграция на 3.x
  30. Репликация: replicaset, топологии
  31. Механика репликации: WAL-стриминг, vclock
  32. Синхронная репликация и выборы лидера (Raft)
  33. Жизненный цикл узла: bootstrap, join, rejoin
  34. vshard: router/storage, виртуальные бакеты
  35. Решардинг и rebalancing бакетов
  36. Запросы поверх шардов: map-reduce, crud
  37. Мониторинг: метрики, Prometheus, Grafana
  38. Логирование и аудит
  39. Бэкапы и восстановление
  40. Безопасность: аутентификация, RBAC, TLS (вы здесь)
  41. Производительность: профилирование, тюнинг
  42. Обновления: схема, rolling upgrade
  43. Деплой в продакшен: Docker, топология (официальные паттерны)
  44. Администрирование через официальный TCM (Tarantool Cluster Manager)
  45. Коннекторы: Python, Go, Java
  46. Ключевые модули (rocks): crud, metrics, queue, expirationd
  47. Capstone: шардированный отказоустойчивый кластер
Краткий обзор

Безопасность Tarantool стоит на трёх китах: аутентификация (кто ты - проверка пароля), авторизация через RBAC (что тебе можно - модель пользователи -> роли -> привилегии) и шифрование трафика TLS (никто не подслушает бинарный канал). Всё это встроено в ядро: отдельного API безопасности нет, вы управляете доступом через системные спейсы и функции box.schema (классический трек) либо через секцию credentials в YAML (декларативный трек 3.x). Цель урока - чтобы вы держали в голове цепочку RBAC и понимали, где физически лежат пользователи и права.

Как это устроено внутри

Где всё хранится. Tarantool держит модель доступа прямо в данных, в двух системных спейсах:
  • _user - пользователи И роли (роль - это пользователь без пароля, отличается полем type). Здесь же лежит хеш пароля.
  • _priv - привилегии: кому (grantee), кто выдал (grantor), на какой объект и какая операция.
Это значит, что права - такие же данные, как и ваши кортежи: они пишутся в WAL, попадают в снапшот и реплицируются на реплики. Изменили грант на мастере - он доедет до всех.

Четыре сущности RBAC.
  • Пользователь - человек или программа, подключающаяся к инстансу.
  • Объект - то, к чему даётся доступ: space, index, function, sequence, user, role, а также universe, lua_eval, lua_call, sql.
  • Привилегия - пара (операция, объект): read, write, create, alter, drop, execute, плюс особые session и usage на universe.
  • Роль - именованный контейнер привилегий. Роли можно вкладывать друг в друга (иерархия), и итоговые права пользователя - это объединение его прямых привилегий и привилегий всех его ролей рекурсивно.
Встроенные пользователи и роли. Есть два пользователя: admin (все права, под ним вы заходите по локальному admin-консоли) и guest (минимум прав, под ним идёт любое анонимное подключение по бинарному порту). Встроенные роли: super (все админ-права), public (выдаётся каждому новому пользователю автоматически - базовый read к системным вещам), replication и sharding (для служебных пользователей кластера; sharding появляется только при YAML-конфигурации).

universe - это вся база. Объект universe представляет box.schema целиком. Грант на universe бьёт по всем объектам разом, поэтому это самый опасный объект. Две неочевидные привилегии живут только на нём: session (право вообще подключиться по IPROTO) и usage (право пользоваться своими привилегиями). Если у пользователя отнять session, он не сможет залогиниться, даже имея пароль; если отнять usage - он подключится, но любая операция упрётся в отказ.

Аутентификация. По умолчанию протокол chap-sha1: сервер шлёт случайную соль (challenge), клиент скрэмблит SHA-1 пароля с этой солью, сервер сверяет - сам пароль по сети не летит. Важная деталь: в _user хеш хранится без соли, так что при утечке снапшота он уязвим к rainbow-таблицам. В Enterprise Edition есть pap-sha256: пароль солится уникальной солью на пользователя (защита от rainbow), но передаётся почти открытым текстом - поэтому PAP обязан работать только поверх TLS. Протокол задаётся через security.auth_type.

Изображение
RBAC: пользователи -> роли -> привилегии

Ключевые команды

Классический трек (box.schema, Lua). Сигнатура одинакова для user и role:

Код: Выделить всё

box.schema.user.grant(username, permissions, object-type, object-name[, {options}])

Код: Выделить всё

-- 1. создаём пользователя с паролем
box.schema.user.create('alice', {password = 'S3cret_pass!'})

-- 2. создаём роль и кладём в неё привилегии
box.schema.role.create('books_reader')
box.schema.role.grant('books_reader', 'read,write', 'space', 'books')
box.schema.role.grant('books_reader', 'execute', 'function', 'sum')

-- 3. выдаём роль пользователю (под капотом - execute на объект role)
box.schema.user.grant('alice', 'execute', 'role', 'books_reader')

-- 4. отдельная прямая привилегия в обход роли
box.schema.user.grant('alice', 'read', 'space', 'writers')

-- что в итоге есть у alice
box.schema.user.info('alice')
Декларативный трек (YAML 3.x). Та же модель, но в конфиге - применяется автоматически при старте:

Код: Выделить всё

credentials:
  roles:
    books_reader:
      privileges:
        - permissions: [ read, write ]
          spaces: [ books ]
  users:
    alice:
      password: 'S3cret_pass!'
      roles: [ books_reader ]
      privileges:
        - permissions: [ read ]
          spaces: [ writers ]
Жёсткость паролей и брутфорса (динамические опции box.cfg / секция security).

Код: Выделить всё

auth_type             = 'chap-sha1'  -- или 'pap-sha256' (EE)
auth_delay            = 10  -- пауза (сек) после серии неудач
auth_retries          = 2   -- сколько попыток до включения паузы
disable_guest         = true -- запретить анонимные удалённые коннекты
password_min_length   = 16
password_lifetime_days= 365 -- срок годности пароля
password_history_length=3   -- не повторять последние 3 пароля
TLS поверх бинарного порта (Enterprise, с 2.10). Включается параметром transport: 'ssl' прямо на listen-URI. Шифрование - TLS 1.2:

Код: Выделить всё

iproto:
  listen:
    - uri: '127.0.0.1:3301'
      params:
        transport: 'ssl'
        ssl_cert_file: 'certs/server.crt'   -- обязателен на сервере
        ssl_key_file:  'certs/server.key'
        ssl_ca_file:   'certs/root_ca.crt'  -- задан -> сверяется подлинность пира
        ssl_ciphers:   'ECDHE-RSA-AES256-GCM-SHA384'
Если ssl_ca_file задан только на сервере - сервер проверяет клиента; если с обеих сторон - взаимная проверка (mTLS).

Частые заблуждения и грабли
  • grant guest на universe = удалённое выполнение кода. Самый разрушительный антипаттерн - box.schema.user.grant('guest','read,write,execute','universe'). Это открывает анонимный RCE. Никогда не давайте guest лишних прав; в проде ставьте disable_guest: true.
  • read,write,execute на universe не даёт drop/alter. Эти три операции не покрывают create/drop/alter. Чужой спейс вы не дропнете, получите "access denied", даже будучи почти всемогущим - нужны отдельные create/drop/alter и доступ к системным спейсам (_space, _index и т.д.).
  • Сменили auth_type - старые пароли не перехешируются. auth_type влияет только на новые. Чтобы существующий пользователь перешёл на pap-sha256, нужно заново задать пароль через box.schema.user.passwd.
  • Владелец объекта получает права автоматически. Кто создал спейс - тот его читает и пишет без явного гранта. Это часто путает при разборе "почему у него есть доступ, я же не выдавал".
  • Отзыв роли - это revoke execute на role, а не отдельная команда. box.schema.user.revoke('alice','execute','role','books_reader').
  • chap-sha1 хранит хеши без соли. Утечка снапшота = риск подбора по rainbow-таблице. Для строгих требований - pap-sha256 (EE) только под TLS.
Правило большого пальса для прода: guest урезан (или выключен), у admin задан пароль, обычным пользователям права выдаются ТОЛЬКО через роли (так проще аудировать и отзывать), бинарный трафик под TLS, аудит-лог (EE) пишет события user_create, grant, auth-фейлы.
Мини-лаба

Поднимите локальный инстанс и в консоли выполните:
  • Создайте спейс books с primary-индексом и функцию-заглушку.
  • Создайте роль reporter, дайте ей только read на books.
  • Создайте пользователя bob с паролем, выдайте ему роль reporter.
  • Через net.box подключитесь под bob и убедитесь: select из books работает, а insert падает с "Write access denied".
  • Посмотрите box.schema.user.info('bob') - найдите там public, session, usage и execute на role reporter. Объясните себе, откуда взялась каждая строчка.
Контрольные вопросы
  • В каких двух системных спейсах физически лежат пользователи, роли и привилегии, и почему изменение прав реплицируется?
  • Чем отличаются привилегии session и usage на universe, и что будет, если отозвать каждую из них у пользователя с паролем?
  • Почему chap-sha1 не передаёт пароль по сети, но при этом снапшот с хешами считается уязвимым, и чем тут лучше pap-sha256?
  • Почему грант 'read,write,execute' на universe не позволит пользователю дропнуть чужой спейс, и что именно нужно добавить?
👍2 ❤️ 🔥2 😄 🤔2
Ответить
← Предыдущая глава
Бэкапы и восстановление
Следующая глава →
Производительность: профилирование, тюнинг

Все главы курса «Tarantool: in-memory СУБД и сервер приложений с нуля до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «Tarantool: СУБД и сервер приложений»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость