Wprowadzenie
W poprzednim artykule przedstawiliśmy podstawy zrozumienia schematów PostgreSQL, mechaniki tworzenia i usuwania oraz omówiliśmy kilka przypadków użycia. W tym artykule omówimy te podstawy i omówimy zarządzanie uprawnieniami związanymi ze schematami.
Więcej przeciążania terminologii
Ale jest jedna sprawa wstępna wymagająca wyjaśnienia. Przypomnijmy, że w poprzednim artykule zajmowaliśmy się możliwym punktem nieporozumienia związanym z przeciążeniem terminu „schemat”. Specjalistyczne znaczenie tego terminu w kontekście baz danych PostgreSQL różni się od tego, jak jest powszechnie używane w systemach zarządzania relacyjnymi bazami danych. Mamy inną podobną możliwą terminologię dotyczącą obecnego tematu związanego ze słowem „publiczny”.
Po początkowym utworzeniu bazy danych, nowo utworzona baza danych Postgresql zawiera predefiniowany schemat o nazwie „public”. Jest to schemat jak każdy inny, ale to samo słowo jest również używane jako słowo kluczowe oznaczające „wszystkich użytkowników” w kontekstach, w których można użyć rzeczywistej nazwy roli, na przykład… czekaj na to… zarządzanie uprawnieniami schematu . Znaczenie i dwa różne zastosowania zostaną wyjaśnione w poniższych przykładach.
Pytania o uprawnienia do schematu
Przed wykonaniem tego konkretu z przykładowym kodem do nadawania i odbierania uprawnień do schematu, musimy przejrzeć, jak badać uprawnienia do schematu. Używając interfejsu wiersza poleceń psql, wypisujemy schematy i związane z nimi uprawnienia za pomocą polecenia \dn+. W przypadku nowo utworzonej bazy danych sampledb widzimy następujący wpis dla schematu publicznego:
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =UC/postgres |
(1 row)
Pierwsze dwie i czwarta kolumna są dość proste:jak wspomniano wcześniej, pokazują domyślnie utworzony schemat o nazwie „public”, opisany jako „standardowy schemat publiczny” i należący do roli „postgres”. (Własność schematu, o ile nie określono inaczej, jest ustawiona na rolę, która tworzy schemat). Trzecia kolumna zawierająca uprawnienia dostępu jest tutaj interesująca. Format informacji o uprawnieniach zawiera trzy elementy:osoba przyznająca uprawnienia, uprawnienia i nadawca uprawnień w formacie „grantee=uprawnienia/nadawca”, to znaczy po lewej stronie znaku równości znajduje się rola otrzymująca uprawnienia, bezpośrednio na prawo od znaku równości znajduje się grupa liter określających konkretny(e) przywilej(e), a na końcu po ukośniku rola, którą przyznano przywilejowi(om). Może istnieć wiele takich specyfikacji informacji o uprawnieniach, oddzielonych znakiem plus, ponieważ uprawnienia są addytywne.
W przypadku schematów istnieją dwa możliwe uprawnienia, które można nadawać oddzielnie:U dla „USAGE” i C dla „CREATE”. Ta pierwsza jest wymagana, aby rola miała możliwość wyszukiwania obiektów bazy danych, takich jak tabele i widoki zawarte w schemacie; drugie uprawnienie pozwala na rolę do tworzenia obiektów bazy danych w schemacie. Istnieją inne litery określające inne uprawnienia związane z różnymi typami obiektów bazy danych, ale w przypadku schematów obowiązują tylko litery U i C.
Tak więc, aby zinterpretować powyższą listę uprawnień, pierwsza specyfikacja mówi nam, że użytkownik postgres otrzymał aktualizację i sam utworzył uprawnienia w publicznym schemacie.
Zwróć uwagę, że w przypadku drugiej specyfikacji powyżej po lewej stronie znaku równości pojawia się pusty ciąg. W ten sposób oznaczane są uprawnienia przyznane wszystkim użytkownikom za pomocą wspomnianego wcześniej słowa kluczowego PUBLIC.
Ta ostatnia specyfikacja przyznawania wszystkim użytkownikom uprawnień do używania i tworzenia w schemacie publicznym jest przez niektórych postrzegana jako prawdopodobnie sprzeczna z najlepszymi praktykami ogólnych zasad bezpieczeństwa, gdzie można zacząć od dostępu ograniczonego domyślnie, wymagającego od administratora bazy danych wyraźnego przyznania odpowiednich i minimalnie niezbędne uprawnienia dostępu. Te liberalne przywileje w publicznym schemacie są celowo konfigurowane w systemie dla wygody i zgodności ze starszymi wersjami.
Zwróć też uwagę, że oprócz zezwalających ustawień uprawnień, jedyną wyjątkową rzeczą w schemacie publicznym jest to, że jest on również wymieniony w ścieżce wyszukiwania, jak omówiliśmy w poprzednim artykule. Dla wygody jest to podobnie:konfiguracja search_path i liberalne przywileje razem powodują, że nowa baza danych może być używana tak, jakby nie istniała koncepcja schematów.
Historyczne tło schematu publicznego
Ten problem dotyczący kompatybilności pochodzi sprzed około piętnastu lat (przed wersją 7.3 PostgreSQL, por. informacje o wydaniu wersji 7.3), kiedy funkcja schematu nie była częścią PostgreSQL. Konfiguracja publicznego schematu z liberalnymi uprawnieniami i obecność search_path, gdy schematy zostały wprowadzone w wersji 7.3, pozwoliły na kompatybilność starszych aplikacji, które nie są świadome schematów, aby działały niezmienione z funkcją zaktualizowanej bazy danych.
W przeciwnym razie nie ma nic szczególnego w publicznym schemacie:niektórzy administratorzy baz danych usuwają go, jeśli ich przypadek użycia nie wymaga tego; inni blokują go, odbierając domyślne uprawnienia.
Pokaż kod — odwoływanie uprawnień
Zróbmy trochę kodu, aby zilustrować i rozwinąć to, o czym rozmawialiśmy do tej pory.
Uprawnieniami do schematu zarządza się za pomocą poleceń GRANT i REVOKE, które odpowiednio dodają i odbierają uprawnienia. Wypróbujemy kilka konkretnych przykładów blokowania schematu publicznego, ale ogólna składnia to:
REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
FROM { [ GROUP ] role_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
Tak więc, jako początkowy przykład blokady, usuńmy uprawnienie tworzenia ze schematu publicznego. Należy zauważyć, że w tych przykładach słowo „publiczne” pisane małymi literami odnosi się do schematu i może zostać zastąpione dowolną inną prawidłową nazwą schematu, która może istnieć w bazie danych. Wielkie słowo „PUBLIC” to specjalne słowo kluczowe, które sugeruje „wszystkich użytkowników” i może zamiast tego zostać zastąpione konkretną nazwą roli lub listą nazw ról oddzielonych przecinkami, aby uzyskać bardziej szczegółową kontrolę dostępu.
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)
Jedyną różnicą w tym wykazie uprawnień do schematu od pierwszego jest brak „C” w drugiej specyfikacji uprawnień, weryfikacja, że nasze polecenie było skuteczne:użytkownicy inni niż użytkownik postgres nie mogą już tworzyć tabel, widoków ani innych obiektów w schemat publiczny.
Zwróć uwagę, że powyższe polecenie odwołujące uprawnienia do tworzenia ze schematu publicznego jest zalecanym łagodzeniem niedawno opublikowanej luki CVE-2018-1058, która wynika z domyślnego ustawienia uprawnień w schemacie publicznym.
Kolejny poziom blokady może wiązać się z całkowitym odmową dostępu do schematu w trybie wyszukiwania poprzez usunięcie przywileju użytkowania:
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)
Ponieważ wszystkie dostępne uprawnienia do schematu dla użytkowników niebędących właścicielami zostały unieważnione, cała druga specyfikacja uprawnień zniknie z powyższej listy.
To, co zrobiliśmy z dwoma oddzielnymi poleceniami, można było zwięźle osiągnąć za pomocą jednego polecenia określającego wszystkie uprawnienia jako:
sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
REVOKE
Dodatkowo możliwe jest również odebranie uprawnień właścicielowi schematu:
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)
ale tak naprawdę nie daje to niczego praktycznego, ponieważ właściciel schematu zachowuje pełne uprawnienia do posiadanych schematów niezależnie od wyraźnego przypisania na podstawie prawa własności.
Liberalne przypisanie uprawnień do schematu publicznego jest specjalnym artefaktem związanym z początkowym tworzeniem bazy danych. Schematy tworzone później w istniejącej bazie danych są zgodne z najlepszymi praktykami uruchamiania bez przypisanych uprawnień. Na przykład sprawdzenie uprawnień schematu po utworzeniu nowego schematu o nazwie „prywatny” pokazuje, że nowy schemat nie ma uprawnień:
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)
Pobierz oficjalny dokument już dziś Zarządzanie i automatyzacja PostgreSQL za pomocą ClusterControlDowiedz się, co musisz wiedzieć, aby wdrażać, monitorować, zarządzać i skalować PostgreSQLPobierz oficjalny dokument Pokaż kod — przyznawanie uprawnień
Ogólna forma polecenia dodania uprawnień to:
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
Za pomocą tego polecenia możemy na przykład zezwolić wszystkim rolom na wyszukiwanie obiektów bazy danych w prywatnym schemacie, dodając uprawnienia użytkowania za pomocą
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)
Zwróć uwagę, jak uprawnienia UC pojawiają się dla właściciela postgres jako pierwsza specyfikacja, teraz, gdy przypisaliśmy do schematu uprawnienia inne niż domyślne. Druga specyfikacja, =U/postgres, odpowiada poleceniu GRANT, które właśnie wywołaliśmy jako postgres użytkownika, przyznający uprawnienia użytkowania wszystkim użytkownikom (gdzie, przypomnij, pusty ciąg po znaku równości oznacza „wszyscy użytkownicy”).
Określonej roli, na przykład o nazwie „użytkownik1”, można nadać uprawnienia zarówno do tworzenia, jak i użytkowania do prywatnego schematu za pomocą:
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)
Nie wspomnieliśmy jeszcze o klauzuli „Z OPCJĄ GRANT” w ogólnym formularzu poleceń. Tak jak się wydaje, ta klauzula zezwala na przyznaną rolę uprawnienia do nadawania określonych uprawnień innym użytkownikom i jest oznaczona na liście uprawnień gwiazdkami dołączonymi do określonego uprawnienia:
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)
Wniosek
To zamyka temat na dzisiaj. Na koniec pamiętaj jednak, że omówiliśmy tylko uprawnienia dostępu do schematu. Chociaż uprawnienie USAGE umożliwia wyszukiwanie obiektów bazy danych w schemacie, aby faktycznie uzyskać dostęp do obiektów dla określonych operacji, takich jak odczyt, zapis, wykonanie itp., rola musi mieć również odpowiednie uprawnienia dla tych operacji na tych konkretnych obiektach bazy danych.