Роли в базе данных

QHB управляет правами доступа к базе данных, используя концепцию ролей. Роль может рассматриваться как пользователь базы данных или группа пользователей базы данных, в зависимости от того, как установлена роль. Роли могут владеть объектами базы данных (например, таблицами и функциями) и могут назначать привилегии для этих объектов другим ролям, чтобы контролировать, кто имеет доступ к каким объектам. Кроме того, можно предоставить членство в роли другой роли, что позволяет роли участника использовать привилегии, назначенные другой роли.

Понятие ролей объединяет понятия «пользователи» и «группы». Любая роль может выступать в роли пользователя, группы или обоих.

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

Роли базы данных

Роли базы данных концептуально полностью отделены от пользователей операционной системы. На практике может быть удобно ввести соответствие, но это не обязательно. Роли базы данных являются глобальными для установленного экземпляра базы данных (а не для отдельной базы данных). Чтобы создать роль, используйте команду SQL CREATE ROLE:

CREATE ROLE name;

name соответствует правилам для идентификаторов SQL: без украшений без специальных символов или в двойных кавычках. (На практике обычно требуется добавить в команду дополнительные параметры, такие как LOGIN. Подробнее см. ниже) Чтобы удалить существующую роль, используйте аналогичную команду DROP ROLE:

DROP ROLE name;

Для удобства программы createuser и dropuser предоставляются в качестве оберток вокруг этих команд SQL, которые можно вызывать из командной строки оболочки:

createuser name
dropuser name

Чтобы определить набор существующих ролей, изучите системный каталог pg_roles, например

SELECT rolname FROM pg_roles;

Метакоманда \du программы qsql также полезна для просмотра существующих ролей.

Для начальной загрузки системы базы данных, недавно инициализированная система всегда содержит одну предопределенную роль. Эта роль всегда является «суперпользователем», и по умолчанию (если она не изменена при запуске initdb) она будет иметь то же имя, что и пользователь операционной системы, который инициализировал экземпляр базы данных. Обычно эта роль будет называться qhb. Чтобы создать больше ролей, сначала необходимо подключиться c этой начальной ролью к БД.

Каждое соединение с сервером базы данных выполняется с использованием имени определенной роли, и эта роль определяет начальные привилегии доступа для команд, выполненных в этом соединении. Имя роли, которое будет использоваться для конкретного подключения к базе данных, указывается клиентом, который инициирует запрос на подключение в зависимости от приложения. Например, программа qsql использует параметр командной строки -U чтобы указать роль для подключения. Многие приложения по умолчанию принимают имя текущего пользователя операционной системы (включая createuser и psq). Поэтому часто удобно поддерживать соответствие имен между ролями и пользователями операционной системы.

Набор ролей базы данных, к которым может подключаться данное клиентское соединение, определяется настройкой аутентификации клиента. (Таким образом, клиент не ограничен подключением в качестве роли, соответствующей пользователю операционной системы, так же, как имя пользователя не обязательно должно совпадать с его или ее настоящим именем) Поскольку идентификация роли определяет набор привилегий, доступных подключенному клиенту, важно тщательно настроить привилегии при настройке многопользовательской среды.

Атрибуты ролей

Роль в базе данных может иметь ряд атрибутов, которые определяют ее привилегии и взаимодействуют с системой аутентификации клиента.

АтрибутОписание
LOGIN (вход в систему)Только роли с атрибутом LOGIN могут использоваться в качестве начального имени роли для подключения к базе данных. Роль с атрибутом LOGIN может рассматриваться как «пользователь базы данных». Чтобы создать роль с правами входа в систему, используйте: CREATE ROLE name LOGIN; CREATE USER name; CREATE USER эквивалентен CREATE ROLE за исключением того, что CREATE USER по умолчанию включает LOGIN, а CREATE ROLE - нет)
SUPERUSER (статус суперпользователя)Суперпользователь базы данных обходит все проверки разрешений, кроме права на вход. Это опасная привилегия, и ее не следует использовать небрежно. Лучше всего выполнять большую часть своей работы в роли, которая не является суперпользователем. Чтобы создать нового суперпользователя базы данных, используйте CREATE ROLE name SUPERUSER. Вы должны сделать это под ролью, которая уже является суперпользователем.
CREATEDB (создание базы данных)Роль должна быть явно предоставлена разрешение на создание баз данных (за исключением суперпользователей, поскольку они обходят все проверки разрешений). Чтобы создать такую роль, используйте CREATE ROLE name CREATEDB.
CREATEROLE (создание ролей)Роли должно быть явно предоставлено разрешение на создание большего количества ролей (за исключением суперпользователей, так как они обходят все проверки разрешений). Чтобы создать такую роль, используйте CREATE ROLE name CREATEROLE. Роль с привилегией CREATEROLE может изменять и CREATEROLE другие роли, а также предоставлять или отзывать членство в них. Однако для создания, изменения, удаления или изменения принадлежности к роли суперпользователя требуется статус суперпользователя; CREATEROLE недостаточно для этого.
REPLICATION (инициирование репликации)Роль должна быть явно предоставлена разрешение на инициирование потоковой репликации (за исключением суперпользователей, так как они обходят все проверки разрешений). Роль, используемая для потоковой репликации, также должна иметь разрешение LOGIN. Чтобы создать такую роль, используйте CREATE ROLE name REPLICATION LOGIN.
PASSWORD (пароль)Пароль имеет значение только в том случае, если метод аутентификации клиента требует от пользователя ввода пароля при подключении к базе данных. password и методы аутентификации md5 используют пароли. Пароли базы данных отделены от паролей операционной системы. Укажите пароль при создании роли с помощью CREATE ROLE name PASSWORD ’ string ’.

Подсказка!!!
Рекомендуется создать роль с привилегиями CREATEDB и CREATEROLE, которая не является суперпользователем, а затем использовать эту роль для всего рутинного управления базами данных и ролями. Такой подход позволяет избежать опасностей работы в качестве суперпользователя для задач, которые на самом деле этого не требуют.

Атрибуты роли могут быть изменены после создания с помощью ALTER ROLE. См. справочные страницы для команд CREATE ROLE и ALTER ROLE для получения подробной информации.

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

ALTER ROLE myname SET enable_indexscan TO off;

Это сохранит настройку (но не установит ее сразу). В последующих соединениях с этой ролью будет выглядеть, как будто SET enable_indexscan TO off был выполнен непосредственно перед началом сеанса. Вы все еще можете изменить этот параметр во время сеанса; это будет только по умолчанию. Чтобы удалить настройку по умолчанию для конкретной роли, используйте ALTER ROLE rolename RESET varname. Обратите внимание, что специфичные для роли значения по умолчанию, прикрепленные к ролям без привилегии LOGIN, довольно бесполезны, поскольку они никогда не будут вызваны.

Ролевая модель управления доступом

Часто удобно группировать пользователей, чтобы упростить управление привилегиями: таким образом, привилегии могут быть предоставлены или отменены для группы в целом. В QHB это достигается созданием роли, представляющей группу, а затем предоставлением членства в роли группы отдельным ролям пользователей.

Чтобы настроить групповую роль, сначала создайте роль:

CREATE ROLE name;

Обычно роль, используемая в качестве группы, не имеет атрибута LOGIN, хотя вы можете установить ее, если хотите.

Когда роль группы существует, вы можете добавлять и удалять участников, используя команды GRANT и REVOKE:

GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;

Вы можете предоставить членство и другим групповым ролям (поскольку на самом деле нет различий между групповыми ролями и не групповыми ролями). База данных не позволит вам настроить циклические циклы членства. Кроме того, не разрешено предоставлять членство в роли для PUBLIC.

Члены групповой роли могут использовать привилегии роли двумя способами. Во-первых, каждый член группы может явно выполнить SET ROLE, чтобы временно «стать» групповой ролью. В этом состоянии сеанс базы данных имеет доступ к привилегиям роли группы, а не к исходной роли входа, и любые созданные объекты базы данных считаются принадлежащими роли группы, а не роли входа. Во-вторых, роли участников, имеющие атрибут INHERIT автоматически используют привилегии ролей, членами которых они являются, включая любые привилегии, унаследованные этими ролями. В качестве примера предположим, что мы сделали:

CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;

Сразу после подключения в качестве роли joe сеанс базы данных будет использовать привилегии, предоставленные непосредственно joe, а также любые привилегии, предоставленные admin, поскольку joe «наследует» привилегии admin. Однако привилегии, предоставленные wheel, ему недоступны, потому что, хотя joe косвенно является членом wheel, членство осуществляется через роль admin которая имеет атрибут NOINHERIT. После:

SET ROLE admin;

сеанс будет использовать только те привилегии, которые предоставлены admin, а не те, которые предоставлены joe. После:

SET ROLE wheel;

сеанс будет использовать только те привилегии, которые предоставлены wheel, а не те, которые предоставлены либо joe либо admin. Исходное состояние привилегий может быть восстановлено любым способом из:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

Заметка
Команда SET ROLE всегда позволяет выбрать любую роль, в которую прямо или косвенно входит исходная роль входа. Таким образом, в приведенном выше примере нет необходимости становиться admin, прежде чем стать wheel.

Заметка
В стандарте SQL существует четкое различие между пользователями и ролями, и пользователи не наследуют привилегии автоматически, в то время как роли делают. Такое поведение может быть получено в QHB, если для ролей, используемых в качестве ролей SQL, используется атрибут INHERIT, а для ролей, используемых в качестве пользователей SQL, - атрибут NOINHERIT. В QHB по умолчанию всем ролям предоставляет атрибут INHERIT.

Атрибуты роли LOGIN, SUPERUSER, CREATEDB и CREATEROLE могут рассматриваться как специальные привилегии, но они никогда не наследуются, как обычные привилегии для объектов базы данных. Вы должны на самом деле установить роль для конкретной роли, имеющей один из этих атрибутов, чтобы использовать этот атрибут. Продолжая приведенный выше пример, мы можем предоставить CREATEDB и CREATEROLE роль admin. Тогда сеанс, соединяющийся как роль joe, не будет иметь этих привилегий сразу, а только после выполнения SET ROLE admin.

Чтобы уничтожить групповую роль, используйте DROP ROLE:

DROP ROLE name;

Любое членство в групповой роли автоматически отменяется (но роли участников не затрагиваются иным образом).

Удаление ролей

Поскольку роли могут владеть объектами базы данных и могут иметь привилегии для доступа к другим объектам, удаление роли часто является не просто вопросом быстрого DROP ROLE. Любые объекты, принадлежащие этой роли, должны быть сначала отброшены или переназначены другим владельцам; и любые разрешения, предоставленные этой роли, должны быть аннулированы.

Право собственности на объекты может передаваться по одному с помощью команд ALTER, например:

ALTER TABLE bobs_table OWNER TO alice;

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

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

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

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

REASSIGN OWNED BY doomed_role TO successor_role;
DROP OWNED BY doomed_role;
-- repeat the above commands in each database of the cluster
DROP ROLE doomed_role;

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

Если попытка DROP ROLE выполняется, пока зависимые объекты все еще остаются, она выдаст сообщения, определяющие, какие объекты необходимо переназначить или отбросить.

Роли по умолчанию

QHB предоставляет набор ролей по умолчанию, которые обеспечивают доступ к определенным, часто необходимым, привилегированным возможностям и информации. Администраторы могут предоставлять эти роли пользователям и/или другим ролям в их среде, предоставляя этим пользователям доступ к указанным возможностям и информации.

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

Таблица 7.1. Роли по умолчанию

РольРазрешенный доступ
pg_read_all_settingsПрочитайте все переменные конфигурации, даже те, которые обычно видны только суперпользователям.
pg_read_all_statsПрочитайте все представления pg_stat_ * и используйте различные статистические расширения, даже те, которые обычно видны только суперпользователям.
pg_stat_scan_tablesВыполните функции мониторинга, которые могут блокировать ACCESS SHARE для таблиц, возможно, в течение длительного времени.
pg_monitorЧитать / выполнять различные виды мониторинга и функции. Эта роль является членом групп pg_read_all_settings, pg_read_all_stats и pg_stat_scan_tables.
pg_signal_backendПодайте сигнал другому бэкэнду, чтобы отменить запрос или завершить сеанс.
pg_read_server_filesРазрешить чтение файлов из любого места, к которому база данных может получить доступ на сервере с помощью COPY и других функций доступа к файлам.
pg_write_server_filesРазрешить запись в файлы в любом месте, к которому база данных может получить доступ на сервере с помощью COPY и других функций доступа к файлам.
pg_execute_server_programРазрешить выполнение программ на сервере базы данных как пользователь, база данных запускается так же, как с COPY и другими функциями, которые позволяют выполнять программу на стороне сервера.

pg_monitor, pg_read_all_settings, pg_read_all_stats и pg_stat_scan_tables предназначены для того, чтобы администраторы могли легко настроить роль для мониторинга сервера базы данных. Они предоставляют набор общих привилегий, позволяющих роли читать различные полезные параметры конфигурации, статистику и другую системную информацию, обычно доступную только суперпользователям.

Роль pg_signal_backend предназначена для того, чтобы администраторы могли включать доверенные, но не суперпользовательские роли, для отправки сигналов другим бэкэндам. В настоящее время эта роль позволяет отправлять сигналы для отмены запроса на другом сервере или завершения его сеанса. Однако пользователь, которому предоставлена эта роль, не может отправлять сигналы бэкэнду, принадлежащему суперпользователю. См. раздел Функции сигнализации сервера.

pg_read_server_files, pg_write_server_files и pg_execute_server_program предназначены для того, чтобы администраторы могли иметь доверенные, но не суперпользовательские роли, которые могут получать доступ к файлам и запускать программы на сервере базы данных в качестве пользователя базы данных. Поскольку эти роли могут получить доступ к любому файлу в файловой системе сервера, они пропускают все проверки разрешений на уровне базы данных при непосредственном доступе к файлам и могут использоваться для получения доступа на уровне суперпользователя, поэтому при предоставлении этих ролей следует соблюдать особую осторожность.

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

Администраторы могут предоставить доступ к этим ролям пользователям с помощью команды GRANT, например:

GRANT pg_signal_backend TO admin_user;

Функция безопасности

Функции, триггеры и политики безопасности на уровне строк позволяют пользователям вставлять код на внутренний сервер, который другие пользователи могут выполнять непреднамеренно. Следовательно, эти механизмы позволяют создавать «троянских коней» относительно легко. Самая сильная защита - жесткий контроль над тем, кто может определять объекты. Там, где это невозможно, пишите запросы, относящиеся только к объектам, имеющим доверенных владельцев. Удалите из search_path общедоступную схему и любые другие схемы, которые позволяют не доверенным пользователям создавать объекты.

Функции выполняются внутри процесса внутреннего сервера с разрешениями операционной системы демона сервера баз данных. Если язык программирования, используемый для функции, допускает неконтролируемый доступ к памяти, можно изменить внутренние структуры данных сервера. Следовательно, среди прочего, такие функции могут обойти любые системы контроля доступа. Языки функций, которые разрешают такой доступ, считаются «ненадежными», а QHB позволяет только суперпользователям создавать функции, написанные на этих языках.