Въведение
В предишна статия представихме основите на разбирането на PostgreSQL схемите, механиката на създаване и изтриване и прегледахме няколко случая на употреба. Тази статия ще разшири тези основи и ще проучи управлението на привилегии, свързани със схеми.
Още претоварване с терминология
Но има един предварителен въпрос, който изисква изясняване. Припомнете си, че в предишната статия се спряхме на възможен момент на объркване, свързан с претоварването на термина „схема“. Специализираното значение на този термин в контекста на PostgreSQL бази данни е различно от това как обикновено се използва в системите за управление на релационни бази данни. Имаме друга подобна възможна терминология за настоящата тема, свързана с думата „публично“.
При първоначалното създаване на база данни, новосъздадената база данни Postgresql включва предварително дефинирана схема, наречена „public“. Това е схема като всяка друга, но същата дума се използва и като ключова дума, която обозначава „всички потребители“ в контексти, в които иначе би могло да се използва действително име на роля, като например ... изчакайте ... управление на привилегиите на схемата . Значението и две различни употреби ще бъдат изяснени в примерите по-долу.
Привилегии на схема за запитване
Преди да направим този конкретен с примерен код за предоставяне и отмяна на привилегии на схема, трябва да прегледаме как да проверим привилегиите на схема. Използвайки интерфейса на командния ред psql, ние изброяваме схемите и свързаните привилегии с командата \dn+. За новосъздадена база данни sampledb виждаме този запис за публичната схема:
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =UC/postgres |
(1 row)
Първите две и четвъртата колони са доста ясни:както беше споменато по-рано, показващи създадената по подразбиране схема, наречена „public“, описана като „стандартна публична схема“ и притежавана от ролята „postgres“. (Собствеността на схемата, освен ако не е посочено друго, е настроена на ролята, която създава схемата.) Тази трета колона, изброяваща привилегиите за достъп, представлява интерес тук. Форматът на информацията за привилегията предоставя три елемента:получателят на привилегията, привилегиите и предоставящият привилегия във формат „получател=привилегии/грант“, тоест вляво от знака за равенство е ролята, получаваща привилегията(ите), непосредствено вдясно от знака за равенство е група от букви, посочващи конкретната(ите) привилегия(и) и накрая след наклонената черта ролята, предоставена на привилегията(ите). Възможно е да има множество такива спецификации за информация за привилегии, изброени разделени със знак плюс, тъй като привилегиите са добавъчни.
За схеми има две възможни привилегии, които могат да бъдат предоставени поотделно:U за „USAGE“ и C за „CREATE“. Първият е необходим, за да може дадена роля да има способността да търси обекти в базата данни, като таблици и изгледи, съдържащи се в схемата; последната привилегия позволява роля за създаване на обекти на база данни в схемата. Има и други букви за други привилегии, свързани с различни типове обекти на база данни, но за схемите се прилагат само U и C.
По този начин, за да тълкуваме списъка с привилегии по-горе, първата спецификация ни казва, че потребителят на postgres е получил актуализацията и сам създава привилегии в публичната схема.
Забележете, че за втората спецификация по-горе се появява празен низ вляво от знака за равенство. Така се обозначават привилегиите, предоставени на всички потребители чрез ключовата дума PUBLIC, спомената по-рано.
Тази последна спецификация за предоставяне на използване и създаване на привилегии в публичната схема на всички потребители се разглежда от някои като вероятно в противоречие с най-добрите практики на общите принципи за сигурност, където човек може да предпочете да започне с достъп, ограничен по подразбиране, изисквайки от администратора на базата данни изрично да предостави подходящи и минимално необходими права за достъп. Тези либерални привилегии върху публичната схема са нарочно конфигурирани в системата за удобство и за съвместимост с наследени версии.
Имайте предвид също, че с изключение на настройките за разрешаващи привилегии, единственото друго нещо специално за публичната схема е, че тя също е посочена в search_path, както обсъдихме в предишната статия. Това е подобно за удобство:конфигурацията на search_path и либералните привилегии заедно водят до използване на нова база данни, сякаш няма такава концепция като схеми.
Историческа справка за публичната схема
Тази загриженост за съвместимостта произлиза от преди около петнадесет години (преди PostgreSQL версия 7.3, вж. бележки за версия 7.3), когато функцията на схемата не беше част от PostgreSQL. Конфигурирането на публичната схема с либерални привилегии и присъствието на search_path, когато схемите бяха въведени във версия 7.3, позволи съвместимостта на по-стари приложения, които не са запознати със схемата, да функционират непроменено с надстроената функция на базата данни.
В противен случай няма нищо друго особено специално за публичната схема:някои DBA я изтриват, ако техният случай на употреба не представлява изискване за това; други го заключват, като отнемат привилегиите по подразбиране.
Покажи ми кода – Отмяна на привилегии
Нека направим някакъв код, за да илюстрираме и разширим това, което обсъждахме досега.
Привилегиите на схемата се управляват с командите GRANT и REVOKE за съответно добавяне и изтегляне на привилегии. Ще опитаме някои конкретни примери за заключване на публичната схема, но общият синтаксис е:
REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
FROM { [ GROUP ] role_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
Така че, като пример за първоначално заключване, нека премахнем привилегията за създаване от публичната схема. Имайте предвид, че в тези примери думата „public“ с малки букви се отнася до схемата и може да бъде заменена с всяко друго валидно име на схема, което може да съществува в базата данни. Главната буква „PUBLIC“ е специалната ключова дума, която предполага „всички потребители“ и вместо това може да бъде заменена с конкретно име на роля или разделен със запетая списък с имена на роли за по-фин контрол на достъпа.
sampledb=# REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =U/postgres |
(1 row)
Единствената разлика в този списък на привилегиите на схемата от първия е отсъствието на „C“ във втората спецификация на привилегията, което потвърждава ефективността на нашата команда:потребителите, различни от потребителя на postgres, вече не могат да създават таблици, изгледи или други обекти в публичната схема.
Обърнете внимание, че горната команда за отнемане на привилегии за създаване от публичната схема е препоръчителното смекчаване на наскоро публикувана уязвимост, CVE-2018-1058, която произтича от настройката за привилегии по подразбиране в публичната схема.
Допълнително ниво на заключване може да доведе до отказ за достъп до схемата за търсене изцяло чрез премахване на привилегията за използване:
sampledb=# REVOKE USAGE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres | standard public schema
(1 row)
Тъй като всички налични привилегии на схема за потребители, които не са собственици, са отменени, цялата спецификация на второто привилегия изчезва в списъка по-горе.
Това, което направихме с две отделни команди, можеше да бъде постигнато накратко с една-единствена команда, определяща всички привилегии като:
sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
REVOKE
Освен това е възможно също да оттеглите привилегии от собственика на схемата:
sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM postgres;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+-------------------+------------------------
public | postgres | | standard public schema
(1 row)
но това всъщност не постига нищо практично, тъй като собственикът на схемата запазва пълните привилегии спрямо притежаваните схеми, независимо от изричното присвояване, просто по силата на собствеността.
Либералното присвояване на привилегии за публичната схема е специален артефакт, свързан с първоначалното създаване на база данни. Създадените впоследствие схеми в съществуваща база данни отговарят на най-добрата практика за стартиране без присвоени привилегии. Например, проверката на привилегиите на схемата след създаване на нова схема с име „частна“ показва, че новата схема няма привилегии:
sampledb=# create schema private;
CREATE SCHEMA
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | |
public | postgres | | standard public schema
(2 rows)
Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книга Покажи ми кода – Предоставяне на привилегии
Общата форма на командата за добавяне на привилегии е:
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
where role_specification can be:
[ GROUP ] role_name
| PUBLIC
| CURRENT_USER
| SESSION_USER
Използвайки тази команда, можем например да позволим на всички роли да търсят обекти на база данни в частната схема, като добавим привилегията за използване с
sampledb=# GRANT USAGE ON SCHEMA private TO PUBLIC;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres |
public | postgres | | standard public schema
(2 rows)
Обърнете внимание как привилегиите на UC се появяват за собственика на postgres като първа спецификация, сега, когато сме присвоили привилегии, различни от подразбиращите се на схемата. Втората спецификация, =U/postgres, съответства на командата GRANT, която току-що извикахме като потребител postgres, предоставяща привилегия за използване на всички потребители (където, припомнете си, празният низ вляво от знака за равенство предполага „всички потребители“).
Конкретна роля, наречена „user1“ например, може да получи както привилегии за създаване, така и за използване на частната схема с:
sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres +|
| | user1=UC/postgres |
public | postgres | | standard public schema
(2 rows)
Все още не сме споменали клаузата „WITH GRANT OPTION“ от общата командна форма. Точно както звучи, тази клауза позволява на дадена роля правомощието сама да предоставя посочените привилегии на други потребители и е обозначена в списъка с привилегии със звездички, добавени към конкретната привилегия:
sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1 WITH GRANT OPTION;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres +|
| | user1=U*C*/postgres |
public | postgres | | standard public schema
(2 rows)
Заключение
Това приключва темата за днес. Като последна забележка обаче, не забравяйте, че обсъдихме само привилегиите за достъп до схема. Докато привилегията USAGE позволява търсене на обекти на база данни в схема, за действителен достъп до обектите за конкретни операции, като четене, писане, изпълнение и т.н., ролята трябва също да има подходящи привилегии за тези операции върху тези конкретни обекти на база данни.