Разграничение доступа
Обзор разграничения доступа
12
Авторские права
© Postgres Professional, 2017–2021
Авторы: Егор Рогов, Павел Лузанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Роли и атрибуты
Подключение к серверу
Привилегии
Политики защиты строк
3
Роли и атрибуты
Роль — пользователь СУБД
роль не связана с пользователем ОС
Свойства роли определяются атрибутами
LOGIN возможность подключения
SUPERUSER суперпользователь
CREATEDB возможность создавать базы данных
CREATEROLE возможность создавать роли
REPLICATION использование протокола репликации
и другие
Роль — это пользователь СУБД.оль также может выступать
в качестве группы пользователей, но об этом будет сказано позже.)
Формально роли никак не связаны с пользователями операционной
системы, хотя многие программы это предполагают, выбирая значения
по умолчанию. Например, psql, запущенный от имени пользователя ОС
student, автоматически использует одноименную роль student (если
в ключах утилиты не указана какая-либо другая роль).
При создании кластера определяется одна начальная роль, имеющая
суперпользовательский доступ (обычно она называется postgres).
В дальнейшем роли можно создавать, изменять и удалять.
Роль обладает некоторыми атрибутами, определяющими ее общие
особенности и права (не связанные с доступом к объектам).
Обычно атрибуты имеют два варианта, например, CREATEDB (дает
право на создание БД) и NOCREATEDB (не дает такого права). Как
правило, по умолчанию выбирается ограничивающий вариант.
Если у роли нет атрибута LOGIN, она не сможет подключиться
к серверу. (Такие роли можно использовать в качестве групповых.)
В таблице перечислены лишь некоторые из атрибутов. Атрибуты
INHERIT и BYPASSRLS рассматривается чуть дальше в этой теме.
5
Подключение
1. Строки pg_hba.conf просматриваются сверху вниз
2. Выбирается первая запись, которой соответствуют
параметры подключения (тип, база, пользователь и адрес)
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
local all all peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
local — сокет all — любая роль
host — TCP/IP имя роли
all — любая БД all — любой IP
имя БД IP/маска
доменное имя
listen_addresses
Для каждого нового клиента сервер определяет, надо ли разрешить
подключение к базе данных. Настройки подключения определяются
в конфигурационном файле pg_hba.conf («host-based authentication»).
Как и с основным конфигурационным файлом postgresql.conf,
изменения вступают в силу только после перечитывания файла
сервером (SELECT pg_reload_conf() в SQL, либо pg_ctl reload из
операционной системы).
При появлении нового клиента сервер просматривает конфигурацион-
ный файл сверху вниз в поисках строки, подходящей к запрашиваемо-
му клиентом подключению. Соответствие определяется по четырем
полям: типу подключения, имени БД, имени пользователя и IP-адресу.
Ниже перечислены только самые основные возможности.
Подключение — local (unix-сокеты, не доступно в Windows) или host
(подключение по протоколу TCP/IP).
База данных – ключевое слово all (соответствует любой БД) или имя
конкретной базы данных.
Пользователь — all или имя конкретной роли.
Адрес — all, конкретный IP-адрес с маской или доменное имя. Не
указывается для типа local. По умолчанию PostgreSQL слушает
входящие соединения только с localhost; обычно параметр
listen_addresses ставят в значение «*» (слушать все интерфейсы)
и дальше регулируют доступ средствами pg_hba.conf.
6
Подключение
3. Выполняется аутентификация указанным методом
4. Удачно — доступ разрешается, иначе — запрещается
(если не подошла ни одна запись — доступ запрещается)
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
local all all peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
trust — верить
reject — отказать
scram-sha-256 и md5 — запросить пароль
peer — спросить ОС
Когда в файле найдена подходящая строка, выполняется аутентифика-
ция указанным в этой строке методом, а также проверяется наличие
атрибута LOGIN и привилегии CONNECT. Если результат проверки
успешен, то подключение разрешается, иначе — запрещается (другие
строки при этом уже не рассматриваются).
Если ни одна из строк не подошла, то доступ также запрещается.
Таким образом, записи в файле должны идти сверху вниз от частного
к общему.
Существует множество методов аутентификации:
Ниже перечислены только самые основные.
Метод trust безусловно разрешает подключение. Если вопросы
безопасности не важны, можно указать «все all» и метод trust — тогда
будут разрешены все подключения.
Метод reject наоборот, безусловно запрещает подключение.
Наиболее распространены методы md5 и более надежный scram-sha-
256, которые запрашивают у пользователя пароль и проверяют его
соответствие паролю, который хранится в системном каталоге
кластера.
Метод peer запрашивает имя пользователя у операционной системы и
разрешает подключение, если имя пользователя ОС и пользователя БД
совпадают (можно установить и другие соответствия имен).
7
Парольная аутентификация
На сервере
пароль устанавливается при создании роли или позже
пользователю без пароля будет отказано в доступе
пароль хранится в системном каталоге pg_authid
Ввод пароля на клиенте
вручную
из переменной окружения PGPASSWORD
из файла ~/.pgpass (строки в формате узел:порт:база:роль:пароль)
Если используется аутентификация по паролю, для роли должен быть
указан эталонный пароль, иначе в доступе будет отказано.
Пароль хранится в системном каталоге в таблице pg_authid.
Пользователь может вводить пароль вручную, а может
автоматизировать ввод. Для этого есть две возможности.
Во-первых, можно задать пароль в переменной окружения
PGPASSWORD на клиенте. Однако это неудобно, если приходится
подключаться к нескольким базам, и не рекомендуется из соображений
безопасности.
Во-вторых, на клиенте можно задать пароли в файле ~/.pgpass.
К файлу должен иметь доступ только владелец, иначе PostgreSQL
проигнорирует его.
9
Привилегии
Привилегии определяют права доступа ролей к объектам
Таблицы
SELECT чтение данных
INSERT вставка строк
UPDATE изменение строк
REFERENCES внешний ключ
DELETE удаление строк
TRUNCATE опустошение таблицы
TRIGGER создание триггеров
Представления
SELECT чтение данных
TRIGGER создание триггеров
можно на уровне столбцов
Привилегии определяются на пересечении объектов кластера и ролей.
Они ограничивают действия, доступные для ролей в отношении этих
объектов.
Список возможных привилегий отличается для объектов различных
типов. Привилегии для объектов основных типов приведены на этом и
следующем слайдах.
Больше всего привилегий определено для таблиц. Некоторые из них
можно определить не только для всей таблицы, но и для отдельных
столбцов.
10
Привилегии
Табличные пространства,
базы данных, схемы
Последовательности
SELECT currval
UPDATE nextval setval
USAGE currval nextval
база данных
схема pg_temp
табл.
пр-во
таблица
таблица
объект
CREATE
USAGE
CREATE
таблица
таблица
объект
TEMPORARY
CREATE
CONNECT
Возможно, несколько неожиданный набор привилегий имеют
последовательности. Выбирая нужные, можно разрешить или
запретить доступ к трем управляющим функциям.
Для табличных пространств есть привилегия CREATE, разрешающая
создание объектов в этом пространстве.
Для баз данных привилегия CREATE разрешает создавать схемы в этой
БД, а для схемы привилегия CREATE разрешает создавать объекты
в этой схеме.
Поскольку точное имя схемы для временных объектов заранее
неизвестно, привилегия на создание временных таблиц вынесена на
уровень БД (TEMPORARY).
Привилегия USAGE схемы разрешает обращаться к объектам в этой
схеме.
Привилегия CONNECT базы данных разрешает подключение к этой БД.
11
Управление привилегиями
Выдача привилегий
роль1: GRANT привилегии ON объект TO роль2;
Отзыв привилегий
роль1: REVOKE привилегии ON объект FROM роль2;
роль1 роль2
привилегии
на объект
Право выдачи и отзыва привилегий на объект имеет владелец этого
объекта (и суперпользователь).
Синтаксис команд GRANT и REVOKE достаточно сложен и позволяет
указывать как отдельные, так и все возможные привилегии; как
отдельные объекты, так и группы объектов, входящие в определенные
схемы и т. п.
12
public
Групповые роли
Включение роли в группу
роль1: GRANT группа TO роль2;
псевдороль public неявно включает
в себя все остальные роли
Исключение роли из группы
роль1: REVOKE группа FROM роль2;
роль1 роль2
группа
группа
роль2
роль1
Любая роль может рассматриваться не только как пользователь СУБД,
но и может включать в себя другие роли, т. е. выступать группой. Роль
может быть включена в другую роль подобно тому, как пользователь
Unix может быть включен в группу.
Возможно в том числе включение групповых ролей в другие групповые
роли (но циклы не допускаются). Вообще, PostgreSQL не делает
никакого различия между «обычными» и «групповыми» ролями.
Смысл включения состоит в том, что для роли становятся доступны
привилегии, которыми обладает групповая роль.
Возможно, удобнее думать о групповой роли как о заранее
сформированном наборе привилегий, который можно «выдать»
обычной роли точно так же, как выдается одиночная привилегия. Это
упрощает администрирование и управление доступом.
Существует псевдороль public, которая неявно включает в себя все
остальные роли. Если выдать какие-либо привилегии роли public, эти
привилегии получат вообще все роли.
Правом на включение и исключение других ролей в данную роль
обладают:
- сама включаемая (исключаемая) роль,
- роль с атрибутом SUPERUSER (суперпользователь),
- роль с атрибутом CREATEROLE.
13
Суперпользователи
Кто входит в категорию
роли с атрибутом SUPERUSER
Права
полный доступ ко всем объектам — проверки не выполняются
В целом можно сказать, что доступ роли к объекту определяется
привилегиями. Но имеет смысл выделить три категории ролей и
рассмотреть их по отдельности.
Проще всего с ролями с атрибутом суперпользователя. Такие роли
могут делать все, что угодно — для них проверки разграничения
доступа не выполняются.
14
Владелец объекта
Кто входит в категорию
изначально — роль, создавшая объект (можно сменить)
а также роли, включенные в роль владельца
Права
изначально все привилегии для объекта (можно отозвать)
действия со своими объектами, не регламентируемые привилегиями,
например: удаление объекта, выдача и отзыв привилегий и т. п.
У каждого объекта есть «владелец» — роль, владеющая этим
объектом. Изначально это роль, создавшая объект, хотя потом
владельца можно сменить. Неочевидный момент: владельцем
считается не только сама роль-владелец, но и любая другая роль,
включенная в нее.
Владелец объекта сразу получает полный набор привилегий для этого
объекта.
В принципе, эти привилегии можно отозвать, но владелец объекта
обладает также неотъемлемым правом совершать действия, не
регламентируемые привилегиями. В частности, он может выдавать и
отзывать привилегии (в том числе и себе самому), удалять объект
и т. п.
15
Остальные роли
Кто входит в категорию
все остальные (не суперпользователи и не владельцы)
Права
доступ в рамках выданных привилегий
обычно наследуют привилегии групповых ролей
(но атрибут NOINHERIT требует явного переключения роли)
Наконец, все остальные роли имеют доступ к объекту только в рамках
выданных им привилегий. В том числе учитываются и привилегии
групповых ролей, в которые эти роли входят (включая псевдороль
public, в которую неявно включены все остальные роли).
Обычно роль сразу обладает всеми «групповыми» полномочиями. Это
поведение можно изменить, указав роли атрибут NOINHERIT — тогда,
чтобы воспользоваться привилегиями групповых ролей, надо будет
явно переключиться с помощью SET ROLE.
Чтобы проверить, есть ли у роли необходимая привилегия в отношении
некоторого объекта, можно воспользоваться функциями has_*_privilege:
Команды psql, описывающие объект, показывают и выданные на него
привилегии (см. раздаточный материал по системному каталогу).
17
Подпрограммы
Единственная привилегия для функций и процедур
EXECUTE выполнение
Характеристики безопасности
SECURITY INVOKER выполняется с правами вызывающего
(по умолчанию)
SECURITY DEFINER выполняется с правами владельца
Для функций и процедур есть единственная привилегия EXECUTE,
разрешающая выполнение этой подпрограммы.
Тонкий момент состоит в том, от имени какого пользователя будет
выполняться подпрограмма. Если подпрограмма объявлена как
SECURITY INVOKER (по умолчанию), она выполняется с правами
вызывающего пользователя. В этом случае операторы внутри
подпрограммы смогут обращаться только к тем объектам, к которым
у вызывающего пользователя есть доступ.
Если же указать фразу SECURITY DEFINER, подпрограмма работает
с правами ее владельца. Это способ позволить другим пользователям
выполнять определенные действия над объектами, к которым у них нет
непосредственного доступа.
18
Привилегии по умолчанию
Привилегии псевдороли public
подключение к любой базе данных
доступ к схеме public и создание в ней объектов
доступ к системному каталогу
выполнение любых подпрограмм
привилегии выдаются автоматически для каждого нового объекта
Настраиваемые привилегии по умолчанию
возможность дополнительно выдать или отозвать привилегии
для только что созданного объекта
Как уже говорилось, псевдороль public включает в себя все остальные
роли, которые, таким образом, пользуются всеми привилегиями,
выданными для public.
При этом public имеет довольно широкий спектр привилегий по
умолчанию. В частности:
- право подключения к любой базе данных (именно поэтому роль alice
смогла подключиться к базе данных несмотря на то, что привилегия
CONNECT не выдавалась ей явно);
- доступ к системному каталогу и схеме public;
- и к тому же — право выполнения любых подпрограмм.
Это, с одной стороны, позволяет комфортно работать, не задумываясь
о привилегиях, но с другой, создает определенные сложности, если
разграничение доступа действительно необходимо.
Описанные выше привилегии появляются у public автоматически при
создании новых объектов. То есть недостаточно просто отозвать
у public привилегию EXECUTE: как только появится новая
подпрограмма, public немедленно получает привилегию на ее
выполнение.
Существует специальный механизм «привилегий по умолчанию»,
который позволяет автоматически выдавать необходимые привилегии
при создании нового объекта. Этот механизм можно использовать и для
отзыва права выполнения функций у псевдороли public.
20
Политики защиты строк
Дополнение к системе привилегий
для разграничения доступа к таблицам на уровне строк
Политика применяется
к определенным ролям
к определенным командам (SELECT, INSERT, UPDATE, DELETE)
Политика определяет условие доступности строки
разрешительная: позволяет видеть строку, если условие выполнено
ограничительная: запрещает видеть строку, если условие не выполнено
отдельные условия (предикаты) для существующих и для новых строк
Привилегии позволяют разграничить доступ на уровне таблиц и
столбцов, а политики защиты строк (row-level security) — на уровне
строк.
Защита строк по умолчанию выключена. При необходимости ее надо
включать явно для каждой таблицы.
Политики определяется для таблицы для набора команд (SELECT,
INSERT, UPDATE, DELETE), и для определенных ролей. По сути,
каждая из политик — это логическое условие (предикат), вычисляемое
для каждой строки выборки. Если условие истинно — доступ к строке
разрешается (достаточно, чтобы доступ позволила хотя бы одна
разрешительная политика и не запретила ни одна ограничительная
политика). В противном случае случае строка не будет видна.
Можно указывать разные предикаты для доступа к существующим
строкам и для добавления новых строк (тогда, например, операция
UPDATE сработает, только если оба предикаты будут истинны).
Предикаты вычисляются с правами вызывающего.
Политики защиты строк не действуют на владельца таблицы (как
правило), на суперпользователей и на роли со специальным атрибутом
BYPASSRLS. Также политики не влияют на проверку ограничений
целостности (уникальность, внешние ключи).
22
Итоги
Роли, привилегии и политики — гибкий механизм,
позволяющий по-разному организовать работу
можно легко разрешить все всем
можно строго разграничить доступ, если это необходимо
При создании новых ролей надо позаботиться
о возможности их подключения к серверу
23
Практика
1. Создайте две роли (пароль должен совпадать с именем):
– employee — сотрудник магазина,
– buyer — покупатель.
Убедитесь, что созданные роли могут подключиться к БД.
2. Отзовите у роли public права выполнения всех функций
и подключения к БД.
3. Разграничьте доступ таким образом, чтобы:
– сотрудник мог только заказывать книги, а также
добавлять авторов и книги,
– покупатель мог только приобретать книги.
Проверьте выполненные настройки в приложении.
1. Сотрудник — внутренний пользователь приложения, аутентификация
выполняется на уровне СУБД.
Покупатель — внешний пользователь. В реальном интернет-магазине
управление такими пользователями ложится на приложение, а все
запросы поступают в СУБД от одной «обобщенной» роли (buyer).
Идентификатор конкретного покупателя может передаваться как
параметр (но в нашем приложении мы этого не делаем).
3. Вообще говоря, разграничение доступа должно быть заложено
и в приложение. В нашем учебном приложении разграничение не
сделано специально: вместо этого на веб-странице можно явно
выбрать роль, от имени которой пойдет запрос в СУБД. Это позволяет
посмотреть, как поведет себя серверная часть при некорректной работе
приложения.
Итак, пользователям нужно выдать:
- Право подключения к БД bookstore и доступ к схеме bookstore.
- Доступ к представлениям, к которым происходит непосредственное
обращение.
- Доступ к функциям, которые вызываются как часть API. Если оставить
функции SECURITY INVOKER, придется выдавать доступ и ко всем
«нижележащим» объектам (таблицам, другим функциям). Однако
удобнее просто объявить API-функции как SECURITY DEFINER.
Разумеется, ролям нужно выдать привилегии только на те объекты,
доступ к которым у них должен быть.
24
Практика
Подпрограммы, объявленные как выполняющиеся с правами
владельца (SECURITY DEFINER), могут использоваться, чтобы
предоставить обычным пользователям возможности, доступные
только суперпользователю.
1. Создайте обычного непривилегированного пользователя
и проверьте, что он не может изменять значение параметра
log_statement.
2. Напишите подпрограмму для включения и выключения
трассировки SQL-запросов так, чтобы созданная роль могла
ей воспользоваться.
1. Вспомните демонстрацию к теме «PL/pgSQL. Отладка». В ней не
возникало сложностей с установкой параметра, поскольку
демонстрация выполнялась от имени роли student, которая является
суперпользователем.