Безопасность Tarantool стоит на трёх китах: аутентификация (кто ты - проверка пароля), авторизация через RBAC (что тебе можно - модель пользователи -> роли -> привилегии) и шифрование трафика TLS (никто не подслушает бинарный канал). Всё это встроено в ядро: отдельного API безопасности нет, вы управляете доступом через системные спейсы и функции box.schema (классический трек) либо через секцию credentials в YAML (декларативный трек 3.x). Цель урока - чтобы вы держали в голове цепочку RBAC и понимали, где физически лежат пользователи и права.
Как это устроено внутри
Где всё хранится. Tarantool держит модель доступа прямо в данных, в двух системных спейсах:
- _user - пользователи И роли (роль - это пользователь без пароля, отличается полем type). Здесь же лежит хеш пароля.
- _priv - привилегии: кому (grantee), кто выдал (grantor), на какой объект и какая операция.
Четыре сущности RBAC.
- Пользователь - человек или программа, подключающаяся к инстансу.
- Объект - то, к чему даётся доступ: space, index, function, sequence, user, role, а также universe, lua_eval, lua_call, sql.
- Привилегия - пара (операция, объект): read, write, create, alter, drop, execute, плюс особые session и usage на universe.
- Роль - именованный контейнер привилегий. Роли можно вкладывать друг в друга (иерархия), и итоговые права пользователя - это объединение его прямых привилегий и привилегий всех его ролей рекурсивно.
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')
Код: Выделить всё
credentials:
roles:
books_reader:
privileges:
- permissions: [ read, write ]
spaces: [ books ]
users:
alice:
password: 'S3cret_pass!'
roles: [ books_reader ]
privileges:
- permissions: [ read ]
spaces: [ writers ]
Код: Выделить всё
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 пароля
Код: Выделить всё
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'
Частые заблуждения и грабли
- 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 не позволит пользователю дропнуть чужой спейс, и что именно нужно добавить?