Управлението на потребителите в PostgreSQL може да бъде трудно. Обикновено новите потребители се управляват съвместно в рамките на няколко ключови области в средата. Често привилегиите са перфектни от едната страна, но са конфигурирани неправилно от другата. Тази публикация в блога ще предостави практически „съвети и трикове“ за потребител или роля, както ще го опознаем, настройка в PostgreSQL.
Предметните области, върху които ще се фокусираме, са:
- Поемане на ролите на PostgreSQL
Ще научите за ролите, атрибутите на ролите, най-добрите практики за наименуване на ролите ви и общите настройки на ролите.
- Файлът pg_hba.conf
В този раздел ще разгледаме един от ключовите файлове и неговите настройки за връзки от страна на клиента и комуникация със сървъра.
- Привилегии и ограничения на ниво база данни, таблица и колона.
Търсите да конфигурирате роли за оптимална производителност и използване? Вашите таблици съдържат ли чувствителни данни, достъпни само за привилегировани роли? И все пак с необходимостта да се позволи на различни роли да изпълняват ограничена работа? Тези и други въпроси ще бъдат изложени в този раздел.
Поемане на ролите на PostgreSQL – Какво е „роля“ и как да се създаде такава?
Разрешенията за достъп до база данни в PostgreSQL се обработват с концепцията за роля, която е подобна на потребител. Ролите могат да представляват и групи потребители в екосистемата на PostgreSQL.
PostgreSQL установява капацитета на ролите да присвояват привилегии на обекти на база данни, които притежават, позволявайки достъп и действия към тези обекти. Ролите имат способността да предоставят членство на друга роля. Атрибутите предоставят опции за персонализиране за разрешено удостоверяване на клиента.
Атрибутите за роли чрез командата CREATE ROLE са налични в официалната документация на PostgreSQL.
По-долу са тези атрибути, които обикновено ще задавате при настройване на нова роля. Повечето от тях се обясняват сами. Въпреки това е предоставено кратко описание, за да се изясни всяко объркване, заедно с примерни употреби.
SUPERUSER - база данни SUPERUSER заслужава внимание. В крайна сметка ролите с този атрибут могат да създават друг СУПЕРПОЛЗВАТЕЛ. Всъщност този атрибут е необходим за създаване на друга роля на SUPERUSER. Тъй като ролите с този атрибут заобикалят всички проверки на разрешенията, дайте тази привилегия разумно.
CREATEDB – Позволява на ролята да създава бази данни.
CREATEROLE – С този атрибут роля може да издаде командата CREATE ROLE. Следователно създайте други роли.
ВХОД - Активира възможността за влизане. Име на роля с този атрибут може да се използва в командата за свързване на клиента. Повече подробности за този атрибут с предстоящи примери.
Някои атрибути имат изрично противоположна команда с име и обикновено са по подразбиране, когато не са посочени.
напр.
СУПЕРПОЛЗВАТЕЛ | NOSUPERUSER
CREATEROLE |NOCREATEROLE
ВХОД |NOLOGIN
Нека разгледаме някои от тези атрибути в действие за различни конфигурации, които можете да настроите, за да започнете.
Създаване и отпадане на роли
Създаването на роля е сравнително лесно. Ето един бърз пример:
postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;
Какво се обърка там? Оказва се, че имената на ролите не могат да започват с нищо друго освен с буква.
„Ами опаковането на името в двойни кавички?“ Да видим:
postgres=# CREATE ROLE "$money_man";
CREATE ROLE
Това проработи, макар че вероятно не е добра идея. Какво ще кажете за специален знак в средата на името?
postgres=# CREATE ROLE money$_man;
CREATE ROLE
Няма проблем там. Дори и без двойни кавички, не беше върната грешка.
Просто не ми харесва структурата на имената на $money_man за потребител. Пускам ви $money_man и започвам отначало. Командата DROP ROLE се грижи за премахването на роля. Ето го в употреба.
postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;
И още една грешка с ролята $money_man. Отново, прибягвайки до двойните кавички.
postgres=# DROP ROLE "$money_man";
DROP ROLE
Привилегията LOGIN
Нека разгледаме два различни потребители, единият с привилегия LOGIN и един без. Ще им задам и пароли.
postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE
Забележка:Паролите, предоставени за горните измислени роли, са само за демонстрационни цели. Винаги трябва да се стремите да предоставяте уникални и втвърдени пароли, когато изпълнявате роли. Докато паролата е по-добра от липсата на парола, утвърдената парола е дори по-добра от тривиалната.
Нека присвоим log_user атрибутите CREATEDB и CREATEROLE с командата ALTER ROLE.
postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE
Можете да проверите тези набори атрибути, като проверите каталога pg_role. Две колони от интерес са rolcreaterole и rolcreatedb. И двете са от булев тип данни, така че трябва да бъдат зададени на t за true за тези атрибути.
Потвърдете с подобна заявка SELECT.
postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb
---------------+-------------
t | t
(1 row)
Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книга Как можете да определите съществуващите роли в базата данни?
Два налични метода са командата psql \du или избор от каталога pg_roles.
Тук и двете се използват.
postgres=> \du
List of roles
Role name | Attributes | Member of
------------+------------------------------------------------------------+-----------
log_user | Create role, Create DB | {}
nolog_user | Cannot login | {}
postgres=> SELECT rolname FROM pg_roles;
rolname
----------------------
nolog_user
log_user
(2 rows)
Влизане
Нека дадем и двете роли, възможност за влизане в сървъра.
psql -U nolog_user -W postgres
Password for user nolog_user:
psql: FATAL: no pg_hba.conf entry for host "[local]", user "nolog_user", database "postgres", SSL off
psql -U log_user -W postgres
Password for user log_user:
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off
За да разрешим този проблем, трябва да копаем в този файл pg_hba.conf. Решението се обсъжда, докато продължаваме в тази публикация, към този конкретен раздел.
Възможни действия
- CREATE ROLE и неговият аналог, DROP ROLE, са вашите команди за внедряване и премахване на роли.
- ALTER ROLE обработва промяната на атрибутите на роля.
- Ролите са валидни във всички бази данни поради дефиниция на ниво клъстер на базата данни.
- Имайте предвид, че създаването на име на роля, започващо със специален знак, изисква да го „адресирате“ с двойни кавички.
- Ролите и техните привилегии се установяват с помощта на атрибути.
- За да установите роли, нуждаещи се от атрибута LOGIN по подразбиране, CREATE USER е незадължителна команда на ваше разположение. Използвани вместо CREATE ROLE име_рола LOGIN, те по същество са равни.
Файлът pg_hba.conf – Създаване на обща основа между сървъра и клиента
Покриването на всички аспекти и настройки за файла pg_hba.conf в една публикация в блога би било в най-добрия случай обезсърчително. Вместо това този раздел ще представи често срещани клопки, които може да срещнете, и решения за отстраняването им.
Успешните връзки изискват конюнктивно усилие от двете части като цяло. Ролите, които се свързват със сървъра, все още трябва да отговарят на ограниченията за достъп, зададени на ниво база данни, след предаване на настройките във файла pg_hba.conf.
Съответните примери за тази връзка са включени в напредъка на този раздел.
За да намерите вашия pg_hba.conf файл, подайте подобна заявка SELECT в pg_settings VIEW. Трябва да сте влезли като СУПЕРПОЛЗВАТЕЛ, за да направите заявка за този ИЗГЛЕД.
postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)
Файлът pg_hba.conf съдържа записи, посочващи един от седемте налични формата за дадена заявка за връзка. Вижте пълния спектър тук .
За целите на тази публикация в блога ще разгледаме настройките, които можете да използвате за локална среда.
Може би този сървър е за вашето продължително обучение и учене (както и моят).
Трябва специално да отбележа, че тези настройки не са оптималните настройки за закалена система, съдържаща множество потребители.
Полетата за този тип връзка са:
local database user auth-method [auth-options]
Къде означават:
локални - се правят опити за свързване с Unix домейн сокети.
база данни - Посочва базата данни(и), наименувани за съвпадението на този запис.
потребител - Потребителското име на базата данни, съответстващо за този запис. Разделен със запетая списък с множество потребители или всички е разрешен и за това поле.
auth-method - Използва се, когато връзка съвпада с този уникален запис. Възможните възможности за избор за това поле са:
- доверие
- отхвърли
- scram-sha-256
- md5
- парола
- gss
- sspi
- идентификация
- връстник
- ldap
- радиус
- сертификат
- пам
- bsd
Редовете, зададени във файла pg_hba.conf за роли nolog_user и log_user изглеждат така:
local all nolog_user password
local all log_user password
Забележка:Тъй като паролата се изпраща в ясен текст, тя не трябва да се използва в ненадеждни среди с ненадеждни мрежи.
Нека разгледаме три интересни колони от pg_hba_file_rules VIEW със заявката по-долу. Отново вашата роля се нуждае от атрибута SUPERUSER, за да подаде заявка за този ИЗГЛЕД.
postgres=# SELECT database, user_name, auth_method
postgres-# FROM pg_hba_file_rules
postgres-# WHERE CAST(user_name AS TEXT) LIKE '%log_user%';
database | user_name | auth_method
----------+--------------+-------------
{all} | {nolog_user} | password
{all} | {log_user} | password
(2 rows)
Можем да видим идентична информация от предоставените по-горе редове, намиращи се във файла pg_hba.conf, както можем от придружаващата заявка. На пръв поглед изглежда, че и двете роли могат да влизат.
Ще тестваме и ще потвърдим.
psql -U nolog_user -W postgres
Password for user nolog_user:
psql: FATAL: role "nolog_user" is not permitted to log in
psql -U log_user -W postgres
Password for user log_user:
psql (10.1)
Type "help" for help.
postgres=>
Ключовият момент тук е, че въпреки че nolog_user и log_user могат да влизат според файла pg_hba.conf, само log_user има право да влезе реално.
Когато log_user е преминал ограниченията за достъп на ниво база данни (като има атрибут LOGIN), nolog_user не го направи.
Нека редактираме реда на log_user във файла pg_hba.conf и да променим името на базата данни, до което тази роля е разрешена. Ето промяната, която показва, че log_user вече може да влезе само в пробната база данни.
local trial log_user password
Първо нека опитаме да влезем в базата данни postgres, до която log_user преди е имал достъп поради флага all.
$ psql -U log_user -W postgres
Password for user log_user:
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off
Сега с пробната база данни log_user има привилегия да
$ psql -U log_user -W trial
Password for user log_user:
psql (10.1)
Type "help" for help.
trial=>
Няма грешка и подканата trial=> показва текущо свързаната база данни.
Тези настройки се прилагат и в сървърната среда, след като се установи връзка.
Нека се опитаме отново да се свържем с тази база данни на postgres:
trial=> \c postgres;
Password for user log_user:
FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off
Previous connection kept
Чрез примерите, представени тук, трябва да сте наясно с опциите за персонализиране на ролите във вашия клъстер.
Забележка:Често се налага презареждане на файла pg_hba.conf, за да влязат в сила промените.
Използвайте помощната програма pg_ctl, за да презаредите вашия сървър.
Синтаксисът би бил:
pg_ctl reload [-D datadir] [-s]
За да разберете къде се намира вашият datadir, можете да направите заявка към системния VIEW pg_settings, ако сте влезли като SUPERUSER с подобна заявка SELECT, както е по-долу.
postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
setting
-----------------------------
/var/lib/postgresql/10/main
(1 row)
След това дайте своя шел на потребителя на postgres (или друг SUPERUSER) с:
$ sudo -u postgres bash
Освен ако не сте добавили помощната програма pg_ctl към вашия $PATH, трябва да я квалифицирате напълно за използване, след което да предадете командата за изпълнение, заедно с местоположението на datadir.
Ето един пример:
$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled
Нека проверим състоянието на сървъра с:
$ /usr/lib/postgresql/10/bin/pg_ctl status -D /var/lib/postgresql/10/main
pg_ctl: server is running (PID: 1415)
/usr/lib/postgresql/10/bin/postgres "-D" "/var/lib/postgresql/10/main" "-c" "config_file=/etc/postgresql/10/main/postgresql.conf"
Възможни действия
- Ролите трябва да предават изисквания както от файла pg_hba.conf, така и от правата за достъп на ниво база данни.
- pg_hba.conf файлът се проверява отгоре надолу за всяка заявка за свързване. Редът във файла е значителен.
Привилегии и ограничения за база данни, таблици и колони – персонализирани роли за задачи и отговорности
За да могат ролите да използват обекти на база данни (таблици, изгледи, колони, функции и т.н.), трябва да им бъдат предоставени права за достъп до тях.
Командата GRANT дефинира тези основни привилегии.
Ще разгледаме няколко примера, за да разберем същността на използването му.
Създаване на бази данни
Тъй като на log_user са предоставени атрибутите CREATEDB и CREATEROLE, можем да използваме тази роля, за да създадем тестова база данни с име trial.
postgres=> CREATE DATABASE trial:
CREATE DATABASE
В допълнение към създаването на нова РОЛЯ:
postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE
Накрая log_user ще се свърже с новата пробна база данни:
postgres=> \c trial;
Password for user log_user:
You are now connected to database "trial" as user "log_user".
trial=>
Забележете, че подканата е променена на името „пробна версия“, което показва, че сме свързани с тази база данни.
Нека използваме log_user за СЪЗДАВАНЕ на фалшива таблица.
trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE
Роля log_user наскоро създаде помощна роля, db_user. Изискваме db_user да има ограничени привилегии за таблица another_workload.
Без съмнение, колоната sensitive_info не трябва да бъде достъпна от тази роля. Командите INSERT, UPDATE и DELETE също не трябва да се предоставят в този момент, докато db_user не отговори на определени очаквания.
Въпреки това, db_user се изисква да издава SELECT заявки. Как можем да ограничим способностите на тези роли в таблицата another_workload?
Първо нека да разгледаме точния синтаксис, открит в документите на PostgreSQL GRANT на ниво таблица.
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
След това прилагаме изискванията, изложени за ролята db_user, като прилагаме специфичен синтаксис.
trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT
Забележете, че непосредствено след ключовата дума SELECT изброихме колоните, до които db_user има достъп. Докато не бъде променено, ако db_user опита SELECT заявки в колоната sensitive_info или всяка друга команда по този въпрос, тези заявки няма да бъдат изпълнени.
Когато db_user е влязъл, ще приложим това на практика, опитвайки се със заявка SELECT да върне всички колони и записи от таблицата.
trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload
Колоната sensitive_info е включена в тази заявка. Следователно не се връщат записи на db_user.
Но db_user може да ИЗБЕРЕ допустимите колони
trial=> SELECT id, first_name, last_name
trial-> FROM another_workload;
id | first_name | last_name
-----+------------+-----------
10 | John | Morris
191 | Jannis | Harper
2 | Remmy | Rosebuilt
(3 rows)
Това работи добре.
Ще тестваме и командите INSERT, UPDATE и DELETE.
trial=> INSERT INTO another_workload(id,first_name,last_name,sensitive_info)
VALUES(17,'Jeremy','Stillman','key code:400Z');
ERROR: permission denied for relation another_workload
trial=> UPDATE another_workload
trial-> SET id = 101
trial-> WHERE id = 10;
ERROR: permission denied for relation another_workload
trial=> DELETE FROM another_workload
trial-> WHERE id = 2;;
ERROR: permission denied for relation another_workload
Като не присвоява команди INSERT, UPDATE или DELETE на db_user, на ролята се отказва достъп до използването им.
С множеството налични опции, конфигурирането на вашата роля е практически неограничено. Можете да ги направите напълно функционални, способни да изпълняват всяка команда или толкова ограничени, колкото изискват вашите изисквания.
Възможни действия
- Ролите се предоставят привилегии за достъп до обекти на база данни чрез командата GRANT.
- Обектите на базата данни и командите срещу тези обекти са силно конфигурируеми в средата на PostgreSQL.
Затваряне
Чрез предоставените примери в тази публикация в блога трябва да имате по-добро разбиране за:
- Създаване на роля със специфични атрибути.
- Задаване на работеща връзка между клиента и сървъра, позволяваща на ролите да влизат в базата данни.
- Силно персонализиране на вашите роли, за да отговарят на индивидуалните изисквания за достъп на ниво база данни, таблици и колони чрез внедряване на необходимите атрибути.