2.5. Управление доступом
В кластере Shardman действует традиционная модель безопасности PostgreSQL, дополненная функциональностью распределённых СУБД. В этом разделе описана данная функциональность, а также даётся общее представление об управлении доступом в кластере Shardman.
2.5.1. Параметры инициализации кластера по настройке управления доступом
Параметры кластера Shardman, связанные с безопасностью, берутся из файла инициализации. Можно изменить их позднее, но это следует делать с осторожностью, помня, что в большинстве случаев любое изменение потребует перезапуска СУБД.
В кластере Shardman есть два специальных пользователя: администратор и пользователь репликации. Shardman и stolon управляют экземплярами СУБД через администраторов. Репликация между контролируемыми экземплярами СУБД осуществляется stolon через пользователей репликации.
Параметры безопасности в файле инициализации задают:
Методы аутентификации для администраторов и пользователей репликации —
PgSuAuthMethod
,PgReplAuthMethod
.Имена для администраторов и пользователей репликации —
PgSuUsername
,PgReplUsername
Пароли для администраторов и пользователей репликации —
PgSuPassword
,PgReplPassword
Правила в файле
pg_hba.conf
, используемые экземплярами СУБД —StolonSpec.pgHBA
Более подробно эти параметры рассматриваются в описании sdmspec.json.
Чтобы задать параметры безопасности, выполните следующие действия:
Проверьте, что пользователь, который будет указан в
PgReplUsername
/PgSuUsername
, имеет праваREPLICATION
/SUPERUSER
во всех группах репликации в кластере, и укажите его действующий пароль вPgReplPassword
/PgSuPassword
.Если всё верно, создайте дамп ключа etcd
shardman/cluster0/data/cluster
(здесь и далее имя кластера Shardman —cluster0
). Например:$
etcdctl --endpoints etcdserver:2379 get --print-value-only shardman/cluster0/data/cluster |jq . > clusterdata.json
В этом примере создаётся дамп ключа
data/cluster
для кластера Shardman с именемcluster0
с сервера etcdetcdserver
, принимающего подключения через порт2379
, дамп форматируется при помощи jq и сохраняется в файлclusterdata.json
.При необходимости отредактируйте дамп и сохраните его обратно в etcd:
$
cat clusterdata.json | etcdctl --endpoints etcdserver:2379 put shardman/cluster0/data/cluster
Изменение этих параметров приведёт к перезапуску СУБД.
В отличие от вышеуказанных параметров, параметр StolonSpec.pgHBA
может быть изменён без перезапуска СУБД. Чтобы изменить его, выполните следующие действия:
Извлеките определение
StolonSpec
изshardman/cluster0/data/cluster
, сохраните в какой-нибудь файл, измените при необходимости и обновите параметры кластера командойshardmanctl config update
:$
etcdctl --endpoints etcdserver:2379 get --print-value-only shardman/cluster0/data/cluster | jq .Spec.StolonSpec . > stolonspec.json
Отредактируйте в файле
stolonspec.json
определениеStolonSpec.pgHBA
соответствующим образом, например:"pgHBA": [ "host all postgres 0.0.0.0/0 scram-sha-256", "host replication postgres 0.0.0.0/0 scram-sha-256", "host replication postgres ::0/0 scram-sha-256", "host all someuser 0.0.0.0/0 scram-sha-256" ],
Примените изменения, внесённые в файл
stolonspec.json
:$
shardmanctl --store-endpoints etcdserver:2379 --cluster-name cluster0 config update -f stolonspec.json
2.5.2. Управление пользователями и ролями
Пользователи и роли в кластере Shardman — это обычные пользователи и роли PostgreSQL. Можно управлять ими отдельно на каждом сервере или глобально, используя DDL на уровне кластера. В Shardman также используются понятия глобальных пользователей и глобальных ролей. И только глобальные пользователи (или роли) могут создавать другие объекты Shardman и владеть ими на уровне кластера, такими как сегментированные или глобальные таблицы. Операции таких пользователей всегда выполняются одновременно на всех группах репликации. Например, когда глобальная роль включается в какую-то другую роль или удаляется, эта операция будет выполняться для всех групп репликации.
Можно создать глобального пользователя, используя оператор CREATE USER ... IN ROLE global
, например:
CREATE USER someuser ENCRYPTED PASSWORD 'somepass' IN ROLE global;
При создании глобального пользователя Shardman автоматически создаёт сопоставление пользователя во всех группах репликации и предоставляет этому пользователю доступ ко всем сторонним серверам, входящим в существующие группы репликации. Поэтому при создании глобального пользователя нужно либо задать незашифрованный пароль, чтобы его можно было сохранить в пользовательском сопоставлении, либо вообще не задавать пароль. Глобальные роли (в том числе глобальные пользователи), для которых не задан пароль, не могут получить доступ к сторонним серверам. Однако глобальной роли можно выдать нужный набор разрешений, чтобы затем предоставлять их пользователям, включая их в эту роль. Кроме того, можно задать пароль для глобального пользователя позже.
Глобальных пользователей может создавать только пользователь с правом CREATEROLE
на всех узлах кластера.
Операторы ALTER
и DROP
для глобальных пользователей транслируются всем группам репликации. Когда роль предоставляется глобальному пользователю, эта операция также транслируется. Переименование глобального пользователя не поддерживается, поскольку это делает недействительными пароли md5/scram-sha-256, хранящиеся в сопоставлениях пользователей.
Список глобальных пользователей хранится в таблице shardman.users
.
Роль, заданная в PgSuUsername
(обычно postgres
), также создаётся как глобальная во время инициализации кластера. Однако роль, заданная в PgReplUsername
, создаётся как локальная в каждой группе репликации.
Роль global
зарезервирована и не может напрямую использоваться в кластере Shardman. Обратите внимание, что «global» является не фактически заданной ролью, а просто зарезервированным словом.
2.5.3. Управление разрешениями в сегментированных таблицах
В Shardman сегментированная таблица — это по сути секционированная таблица, где секции представляют собой либо локальные сегменты, либо сторонние таблицы, ссылающиеся на сегменты в других группах репликации.
Разрешения, установленные для сегментированной таблицы, транслируются для всех групп репликации и всех секций таблицы.
Когда в кластер добавляется новая группа репликации, клиент shardmanctl копирует схему из случайной существующей группы репликации в новую. Он также создаёт сторонний сервер для новой группы репликации во всех существующих группах репликации и пересоздаёт сторонние серверы в новых группах репликации. Разрешения для созданных сторонних серверов и сопоставления пользователей копируются со случайного стороннего сервера в существующей группе репликации. В новой группе репликации для каждой секции сегментированной таблицы shardmanctl создаёт стороннюю таблицу, ссылающуюся на существующий сегмент, и заменяет секцию этой сторонней таблицей. Позже некоторые из этих сторонних таблиц могут быть заменены на реальные таблицы. Это происходит на этапе перебалансировки команды shardmanctl nodes add
, если перебалансировка включена. Данные для этих секций переносятся с существующих узлов с использованием логической репликации. Когда shardmanctl создаёт таблицы (или сторонние таблицы), он копирует разрешения из родительской таблицы. В родительской таблице уже должны быть правильные разрешения, поскольку они были скопированы из существующей группы репликации.
2.5.3.1. Примеры
Для выполнения команд в данном примере требуются права администратора.
Чтобы создать сегментированную таблицу и глобального пользователя, а затем предоставить ему доступ только для чтения к таблице, можно использовать следующие операторы:
CREATE USER someuser ENCRYPTED PASSWORD 'somepass' IN ROLE global; CREATE TABLE pgbench_branches ( bid integer NOT NULL PRIMARY KEY, bbalance integer, filler character(88) ) WITH (distributed_by = 'bid', num_parts = 8); GRANT SELECT ON pgbench_branches TO someuser;
Чтобы разрешить пользователю someuser
доступ к кластеру Shardman, необходимо задать соответствующие параметры в pg_hba.conf
(как было показано здесь).
Теперь предположим, что командой shardmanctl nodes add
в кластер добавлено новое звено, например:
$
shardmanctl --store-endpoints http://etcdserver:2379 --cluster-name cluster0 nodes add -n newnode1,newnode2
В этом примере некоторые фрагменты таблицы pgbench_branches
переносятся в новые группы репликации, и пользователю someuser
выдаётся право SELECT
для этой таблицы. Позже можно удалить пользователя someuser
из всех групп репликации в кластере одной командой:
DROP USER someuser;