Как управлять ПРИВИЛЕГИЯМИ ПО УМОЛЧАНИЮ для ПОЛЬЗОВАТЕЛЕЙ на DATABASE vs SCHEMA?

48

Я хочу перенести довольно простое внутреннее приложение, управляемое базой данных, из SQLite3 в PostgreSQL 9.3 и ужесточить права доступа к БД.

Приложение в настоящее время состоит из команды для обновления данных; и один, чтобы запросить это. Естественно, мне также нужно поддерживать базу данных другими способами (создавать новые таблицы, представления, триггеры и т. Д.).

Хотя это приложение будет единственным, размещенным на сервере вначале, я предпочел бы испечь в предположении, что оно может быть размещено на сервере с другими базами данных в будущем, а не шифровать его позже, если в этом возникнет необходимость. будущее.

Я думаю, что это будет довольно распространенный набор требований, но у меня возникают проблемы с поиском простого учебника, объясняющего, как настроить новую базу данных в PostgreSQL с таким разделением пользователей и привилегий. Ссылки продолжаются подробно о группах, пользователях, ролях, базах данных, схемах и области; но я нахожу их запутанными.

Вот что я пробовал до сих пор (изнутри psqlкак «postgres»):

CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;
\connect hostdb
CREATE SCHEMA hostdb;
CREATE USER hostdb_admin WITH PASSWORD 'youwish';
CREATE USER hostdb_mgr   WITH PASSWORD 'youwish2';
CREATE USER hostdb_usr WITH PASSWORD 'youwish3';

GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin;
GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT ON TABLES TO hostdb_usr;

Но я не получаю предполагаемую семантику. Я хочу, чтобы он был настроен таким образом, чтобы только hostdb_adminтаблицы могли создавать (и удалять и изменять); hostdb_mgrможет читать, вставлять, обновлять и удалять на все таблицы по умолчанию; и hostdb_usrможет только читать все таблицы (и представления).

Когда я попробовал это, я обнаружил, что могу создавать таблицы hostdbкак любой из этих пользователей; но для каждого пользователя я мог только читать или изменять таблицы, созданные этим пользователем - если я не использую явные GRANT.

Я предполагаю, что между CREATE DATABASEи CREATE SCHEMAчем- то не хватает , что-то, чтобы применить SCHEMAк DATABASE?

(По мере того, как дела будут продвигаться дальше, у меня также возникнут вопросы о применении аналогичных ограничений TRIGGERS, хранимых процедур VIEWSи, возможно, других объектов).

Где я могу найти достойное руководство, учебник или видео сериал по этому вопросу?

Джим Деннис
источник
2
Я думаю (по крайней мере, часть) ваша проблема лежит в publicпсевдороле. Эту роль можно рассматривать как роль, членом которой является любая другая роль (пользователь, группа - все они одинаковы). Попробуйте удалить из него привилегии, например REVOKE CREATE ON SCHEMA hostdb FROM public,. Отмена прав на уровне базы данных, как вы это сделали, отключает только некоторые разрешения на уровне базы данных, не влияя на схемы или таблицы.
Дезсо
@dezso: может быть неправильное представление о привилегиях по умолчанию для схем. Только схема по умолчанию publicпроисходит с привилегиями для PUBLIC. Кроме этого, нет никаких привилегий по умолчанию для новых схем. Так что это не влияет на продемонстрированный вариант использования. Смотрите главу в моем ответе.
Эрвин Брандштеттер

Ответы:

86

Где я могу найти достойное руководство, учебник или видео сериал по этому вопросу?

Вы найдете все в руководстве. Ссылки ниже.
Конечно, дело не тривиальное, а иногда запутанное. Вот рецепт для варианта использования:

Рецепт

Я хочу, чтобы он был настроен таким образом, чтобы только hostdb_adminтаблицы могли создавать (и удалять и изменять); может читать, вставлять, обновлять и удалять на все таблицы по умолчанию; и может только читать все таблицы (и представления).
hostdb_mgr
hostdb_usr

Как суперпользователь postgres:

CREATE USER schma_admin WITH PASSWORD 'youwish';
-- CREATE USER schma_admin WITH PASSWORD 'youwish' CREATEDB CREATEROLE; -- see below
CREATE USER schma_mgr   WITH PASSWORD 'youwish2';
CREATE USER schma_usr   WITH PASSWORD 'youwish3';

Если вам нужен более мощный администратор, который также может управлять базами данных и ролями, добавьте атрибуты роли CREATEDBиCREATEROLE выше.

Предоставьте каждой роли следующий более высокий уровень, чтобы все уровни «наследовали» как минимум набор привилегий следующего более низкого уровня (каскадирование):

GRANT schma_usr TO schma_mgr;
GRANT schma_mgr TO schma_admin;

CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;  -- see notes below!

GRANT CONNECT ON DATABASE hostdb TO schma_usr;  -- others inherit

\connect hostdb  -- psql syntax

Я называю схему schma(не hostdbкоторая может сбить с толку). Выберите любое имя. По желанию сделать schma_adminвладельца схемы:

CREATE SCHEMA schma AUTHORIZATION schma_admin;

SET search_path = schma;  -- see notes

ALTER ROLE schma_admin IN DATABASE hostdb SET search_path = schma; -- not inherited
ALTER ROLE schma_mgr   IN DATABASE hostdb SET search_path = schma;
ALTER ROLE schma_usr   IN DATABASE hostdb SET search_path = schma;

GRANT USAGE  ON SCHEMA schma TO schma_usr;
GRANT CREATE ON SCHEMA schma TO schma_admin;

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT SELECT                           ON TABLES TO schma_usr;  -- only read

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO schma_mgr;  -- + write, TRUNCATE optional

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO schma_mgr;  -- SELECT, UPDATE are optional 

Для and drop and alterзаметок ниже.

По мере того, как дела продвигаются вперед, у меня также возникают вопросы о применении аналогичных ограничений TRIGGERS, хранимых процедур VIEWSи, возможно, других объектов.

Взгляды особенные. Для одного:

... (но учтите, что ALL TABLESсчитается, что он включает в себя представления и сторонние таблицы).

И для обновляемых представлений :

Обратите внимание, что пользователь, выполняющий вставку, обновление или удаление в представлении, должен иметь соответствующую привилегию вставки, обновления или удаления в представлении. Кроме того, владелец представления должен иметь соответствующие привилегии для базовых базовых отношений, но пользователю, выполняющему обновление, не требуются какие-либо разрешения для базовых базовых отношений (см. Раздел 38.5 ).

Триггеры тоже особенные. Вам нужна TRIGGERпривилегия на стол, и:

Но мы уже чрезмерно расширяем сферу этого вопроса ...

Важные заметки

Владение

Если вы хотите разрешить schma_admin(самостоятельно) удалять и изменять таблицы, сделайте роль владельцем всех объектов. Документация:

Право удалить объект или каким-либо образом изменить его определение не рассматривается как предоставляемая привилегия; это присуще владельцу, и не может быть предоставлено или отменено. (Однако аналогичный эффект можно получить, предоставив или отменив членство в роли, которой принадлежит объект; см. Ниже.) Владелец неявно также имеет все параметры предоставления объекта.

ALTER TABLE some_tbl OWNER TO schma_admin;

Или создайте все объекты с рольюschma_adminдля начала, тогда вам не нужно явно указывать владельца. Это также упрощает привилегии по умолчанию, которые вам нужно установить только для одной роли:

Существующие объекты

Права по умолчанию применяются только для вновь созданных объектов и только для конкретной роли, с которой они созданы. Вы также захотите адаптировать разрешения для существующих объектов:

То же самое применимо, если вы создаете объекты с ролью, которая не имеет DEFAULT PRIVILEGESустановленной, например суперпользователь postgres. Переприсвоить собственности на schma_adminи набор привилегий вручную - или набор DEFAULT PRIVILEGESдля , postgresа также (при подключении к правой БД!):

ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ...  -- etc.

Права по умолчанию

Вы упустили важный аспект ALTER DEFAULT PRIVILEGESкоманды. Это относится к текущей роли, если не указано иное:

Права по умолчанию применяются только к текущей базе данных. Таким образом, вы не связываетесь с другими базами данных в кластере БД. Документация:

для всех объектов, созданных в текущей базе данных

Вы можете также необходимо установить права по умолчанию для FUNCTIONSи TYPES(не только TABLESи SEQUENCES), но те , которые не могут быть необходимы.

Права по умолчанию для PUBLIC

Предоставленные по умолчанию привилегии PUBLICявляются зачаточными и переоцениваются некоторыми. Документация:

PostgreSQL предоставляет права по умолчанию для некоторых типов объектов PUBLIC. Никакие привилегии не предоставляются PUBLICпо умолчанию для таблиц, столбцов, схем или табличных пространств. Для других типов предоставляются PUBLICследующие привилегии по умолчанию : CONNECTи CREATE TEMP TABLEдля баз данных; EXECUTEпривилегия для функций; и USAGE привилегия для языков.

Жирный акцент мой. обычно одной команды выше достаточно, чтобы охватить все:

REVOKE ALL ON DATABASE hostdb FROM public;

В частности, никакие привилегии по умолчанию не предоставляются PUBLICдля новых схем. Может показаться странным, что схема по умолчанию с именем «public» начинается с ALLпривилегий для PUBLIC. Это просто удобная функция для облегчения запуска с вновь созданными базами данных. Это никак не влияет на другие схемы. Вы можете отменить эти привилегии в базе данных шаблонов template1, после чего все вновь созданные базы данных в этом кластере начнутся без них:

\connect template1
REVOKE ALL ON SCHEMA public FROM public;

Привилегия TEMP

Поскольку мы отозвали все привилегии hostdbс PUBLIC, обычные пользователи не могут создавать временные таблицы, если мы явно не разрешаем это. Вы можете или не можете добавить это:

GRANT TEMP ON DATABASE hostdb TO schma_mgr;

search_path

Не забудьте установить search_path. Если у вас есть только одна база данных в кластере, вы можете просто установить глобальное значение по умолчанию в postgresql.conf. Иначе (более вероятно) установить его как свойство базы данных, или просто для задействованных ролей, или даже для комбинации обоих. Подробности:

Возможно, вы захотите установить его, schma, publicесли вы используете общедоступную схему, или даже (менее вероятно) $user, schma, public...

Альтернативой может быть использование схемы по умолчанию «public», которая должна работать с настройками по умолчанию, search_pathесли только вы не изменили это. Не забудьте отозвать привилегии для PUBLICв этом случае.

Связанный

Эрвин Брандштеттер
источник
Я искал, как добавить привилегии администратора по умолчанию для вновь созданного суперпользователя, поэтому мне не нужно было бы давать ему дополнительные права на каждую таблицу. И я нашел это. И thisвыглядит как инструкция для космического корабля ...
Денис Матафонов
@DenisMatafonov: Суперпользователи получают все привилегии автоматически. Я предлагаю вам начать новый вопрос со специфики вашего дела. Комментарии не место. Вы всегда можете ссылаться на связанные вопросы / ответы для контекста.
Эрвин Брандштеттер
Да, у суперпользователей есть все права доступа, но вы не можете обобщить их привилегии по умолчанию. Было бы неплохо установить привилегии по умолчанию для роли в схеме, и эти значения по умолчанию применяются ко всем членам роли при создании таблиц в схеме. Например, чтобы сказать: «Убедитесь, что все таблицы, созданные в этой схеме кем-либо из команды разработчиков, будут доступны для чтения любому члену группы отчетности». Короче говоря, я хочу, чтобы члены роли, создающей таблицу, наследовали ее привилегии по умолчанию.
комбинатор