PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Uprawnienia PostgreSQL i zarządzanie użytkownikami — co powinieneś wiedzieć

Zarządzanie użytkownikami w PostgreSQL może być trudne. Zazwyczaj nowi użytkownicy są zarządzani wspólnie w kilku kluczowych obszarach środowiska. Często uprawnienia są idealne na jednym froncie, ale niepoprawnie skonfigurowane na drugim. Ten post na blogu dostarczy praktycznych „Wskazówek i trików” dla użytkownika lub roli, jak się dowiemy, konfiguracji w PostgreSQL.

Skoncentrujemy się na następujących obszarach tematycznych:

  • Przyjmowanie ról PostgreSQL

Dowiesz się o rolach, atrybutach ról, najlepszych praktykach dotyczących nazewnictwa ról i typowych konfiguracjach ról.

  • Plik pg_hba.conf

W tej sekcji przyjrzymy się jednemu z kluczowych plików i jego ustawieniom dotyczącym połączeń po stronie klienta i komunikacji z serwerem.

  • Uprawnienia i ograniczenia na poziomie bazy danych, tabeli i kolumny.

Chcesz skonfigurować role w celu uzyskania optymalnej wydajności i wykorzystania? Czy Twoje tabele zawierają poufne dane, dostępne tylko dla ról uprzywilejowanych? Jednak z koniecznością umożliwienia różnym rolom wykonywania ograniczonej pracy? Te i inne pytania zostaną przedstawione w tej sekcji.

Przyjmowanie ról w PostgreSQL — co to jest „rola” i jak ją utworzyć?

Uprawnienia dostępu do bazy danych w PostgreSQL są obsługiwane za pomocą koncepcji roli, która jest podobna do użytkownika. Role mogą również reprezentować grupy użytkowników w ekosystemie PostgreSQL.

PostgreSQL ustanawia zdolność ról do przypisywania uprawnień do obiektów bazy danych, których są właścicielami, umożliwiając dostęp i działania na tych obiektach. Role mają możliwość przyznania członkostwa innej roli. Atrybuty zapewniają opcje dostosowywania dla dozwolonego uwierzytelniania klienta.

Atrybuty ról za pomocą polecenia CREATE ROLE są dostępne w oficjalnej dokumentacji PostgreSQL.

Poniżej znajdują się te atrybuty, które zwykle przypisujesz podczas konfigurowania nowej roli. Większość z nich nie wymaga wyjaśnień. Przedstawiono jednak krótki opis, aby wyjaśnić wszelkie nieporozumienia wraz z przykładowymi zastosowaniami.

SUPERUSER - Baza danych SUPERUSER zasługuje na słowo ostrzeżenia. Podsumowując, role z tym atrybutem mogą tworzyć kolejnego SUPERUSER. W rzeczywistości ten atrybut jest wymagany do utworzenia kolejnej roli SUPERUSER. Ponieważ role z tym atrybutem omijają wszystkie kontrole uprawnień, rozsądnie przyznaj to uprawnienie.

CREATEDB — Umożliwia tworzenie baz danych.

CREATEROLE — z tym atrybutem rola może wydać polecenie CREATE ROLE. Dlatego stwórz inne role.

LOGOWANIE - Włącza możliwość logowania. W poleceniu połączenia klienta można użyć nazwy roli z tym atrybutem. Więcej szczegółów na temat tego atrybutu w nadchodzących przykładach.

Niektóre atrybuty mają wyraźne przeciwne biegunowe nazwane polecenie i zazwyczaj są one domyślne, gdy nie są określone.

np.
SUPERUSER | NOSUPERUSER
CREATEROLE |NOCREATEROLE
LOGOWANIE |NOLOGOWANIE

Przyjrzyjmy się niektórym z tych atrybutów w działaniu dla różnych konfiguracji, które możesz skonfigurować, aby rozpocząć.

Tworzenie i usuwanie ról

Tworzenie roli jest stosunkowo proste. Oto krótki przykład:

postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;

Co tam poszło nie tak? Okazuje się, że nazwy ról nie mogą zaczynać się od niczego poza literą.

„A co z umieszczaniem nazwy w podwójnych cudzysłowach?” Zobaczmy:

postgres=# CREATE ROLE "$money_man";
CREATE ROLE

To zadziałało, choć prawdopodobnie nie jest to dobry pomysł. Co powiesz na znak specjalny w środku nazwy?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Nie ma problemu. Nawet bez podwójnych cudzysłowów nie został zwrócony żaden błąd.

Po prostu nie przepadam za strukturą nazwy $money_man dla użytkownika. Wrzucam ci $money_man i zaczynam od nowa. Polecenie DROP ROLE zajmuje się usunięciem roli. Tutaj jest w użyciu.

postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;

I kolejny błąd z rolą $money_man. Ponownie, uciekając się do podwójnych cudzysłowów.

postgres=# DROP ROLE "$money_man";
DROP ROLE

Uprawnienie LOGOWANIE

Przyjrzyjmy się dwóm różnym użytkownikom, jednemu z uprawnieniem LOGIN, a drugiemu bez. Przydzielę im również hasła.

postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE

Uwaga:hasła dostarczone do powyższych fikcyjnych ról służą wyłącznie do celów demonstracyjnych. Podczas wdrażania ról należy zawsze dążyć do zapewnienia unikalnych i wzmocnionych haseł. Chociaż hasło jest lepsze niż brak hasła, wzmocnione hasło jest nawet lepsze niż trywialne.

Przypiszmy log_user atrybuty CREATEDB i CREATEROLE za pomocą polecenia ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Możesz zweryfikować te ustawione atrybuty, sprawdzając katalog pg_role. Dwie interesujące kolumny to rolcreaterole i rolcreatedb. Oba są typu danych logicznych, więc powinny być ustawione na t dla wartości true dla tych atrybutów.

Potwierdź za pomocą podobnego zapytania SELECT.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
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

Jak możesz określić istniejące role obecne w bazie danych?

Dwie dostępne metody to polecenie psql \du lub wybór z katalogu pg_roles.

Tutaj obaj są w użyciu.

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)

Logowanie

Dajmy obu rolom możliwość zalogowania się do serwera.

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

Aby rozwiązać ten problem, musimy zagłębić się w plik pg_hba.conf. Rozwiązanie zostanie omówione w dalszej części tego posta, do tej konkretnej sekcji.

Przystępne dania na wynos

  • CREATE ROLE i jej odpowiednik, DROP ROLE, są Twoimi głównymi poleceniami do wdrażania i usuwania ról.
  • ALTER ROLE obsługuje zmianę atrybutów roli.
  • Role są ważne we wszystkich bazach danych ze względu na definicję na poziomie klastra bazy danych.
  • Pamiętaj, że utworzenie nazwy roli zaczynającej się od znaku specjalnego wymaga „zaadresowania” jej podwójnymi cudzysłowami.
  • Role i ich uprawnienia są ustalane za pomocą atrybutów.
  • Aby ustanowić role wymagające domyślnie atrybutu LOGIN, CREATE USER jest opcjonalnym poleceniem do Twojej dyspozycji. Używane zamiast CREATE ROLE role_name LOGIN, są zasadniczo równe.

Plik pg_hba.conf — ustanawianie wspólnej płaszczyzny między serwerem a klientem

Objęcie wszystkich aspektów i ustawień pliku pg_hba.conf w jednym poście na blogu byłoby w najlepszym razie zniechęcające. Zamiast tego w tej sekcji zostaną przedstawione typowe pułapki, które możesz napotkać, oraz rozwiązania, które mogą im zaradzić.

Udane połączenia wymagają połączonego wysiłku obu części jako całości. Role łączące się z serwerem muszą nadal spełniać ograniczenia dostępu ustawione na poziomie bazy danych, po przekazaniu ustawień w pliku pg_hba.conf.

Odpowiednie przykłady tej relacji są dołączane w miarę postępów w tej sekcji.

Aby zlokalizować plik pg_hba.conf, wydaj podobne zapytanie SELECT w WIDOKU pg_settings. Aby wysłać zapytanie do tego WIDOKU, musisz być zalogowany jako SUPERUSER.

postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

Plik pg_hba.conf zawiera rekordy określające jeden z siedmiu dostępnych formatów dla danego żądania połączenia. Zobacz pełne spektrum tutaj.

Na potrzeby tego wpisu na blogu przyjrzymy się ustawieniom, których można używać w środowisku lokalnym.

Być może ten serwer służy do ciągłego uczenia się i nauki (tak jak mój).

Muszę zwrócić szczególną uwagę, że te ustawienia nie są optymalnymi ustawieniami dla wzmocnionego systemu zawierającego wielu użytkowników.

Pola dla tego typu połączenia to:

local database user auth-method [auth-options]

Gdzie mają na myśli:

local - próba nawiązania połączenia z gniazdami w domenie Unix.

baza danych — określa bazy danych nazwane dla tego dopasowania rekordu.

użytkownik — nazwa użytkownika bazy danych pasująca do tego rekordu. W tym polu dozwolona jest również lista rozdzielonych przecinkami wielu lub wszystkich użytkowników.

auth-method — jest używana, gdy połączenie pasuje do tego unikalnego rekordu. Możliwe wybory dla tego pola to:

  • zaufanie
  • odrzuć
  • scram-sha-256
  • md5
  • hasło
  • gss
  • spi
  • identyfikator
  • rówieśnik
  • ldap
  • promień
  • certyfikat
  • pam
  • bsd

Linie ustawione w pliku pg_hba.conf dla ról nolog_user i log_user wyglądają tak:

local all nolog_user password
local all log_user password

Uwaga:ponieważ hasło jest przesyłane w postaci zwykłego tekstu, nie należy go używać w niezaufanych środowiskach z niezaufanymi sieciami.

Przyjrzyjmy się trzem interesującym kolumnom z VIEW pg_hba_file_rules z poniższym zapytaniem. Ponownie twoja rola potrzebuje atrybutu SUPERUSER, aby wysłać zapytanie do tego WIDOKU.

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)

Możemy zobaczyć identyczne informacje z podanych powyżej linii znajdujących się w pliku pg_hba.conf, jak możemy z towarzyszącego zapytania. Na pierwszy rzut oka wygląda na to, że obie role mogą się zalogować.

Przetestujemy i potwierdzimy.

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=>

Kluczową kwestią jest tutaj to, że chociaż nolog_user i log_user mogą się logować zgodnie z plikiem pg_hba.conf, tylko log_user może się zalogować.

Tam, gdzie log_user przeszedł ograniczenia dostępu na poziomie bazy danych (poprzez posiadanie atrybutu LOGIN), nolog_user nie.

Zmodyfikujmy wiersz log_user w pliku pg_hba.conf i zmieńmy nazwę bazy danych, do której ta rola ma dostęp. Oto zmiana wskazująca, że ​​log_user może teraz zalogować się tylko do testowej bazy danych.

local trial log_user password

Najpierw spróbujmy zalogować się do bazy danych postgres, do której log_user miał wcześniej dostęp ze względu na flagę 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

Teraz z próbną bazą danych log_user ma uprawnienia do

$ psql -U log_user -W trial
Password for user log_user: 
psql (10.1)
Type "help" for help.
trial=>

Nie ma błędu, a monit trial=> pokazuje aktualnie podłączoną bazę danych.

Te ustawienia obowiązują również w środowisku serwera, po nawiązaniu połączenia.

Spróbujmy ponownie połączyć się z tą bazą danych 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

Dzięki przedstawionym tutaj przykładom powinieneś zdawać sobie sprawę z opcji dostosowywania ról w swoim klastrze.

Uwaga:często wymagane jest ponowne załadowanie pliku pg_hba.conf, aby zmiany zaczęły obowiązywać.

Użyj narzędzia pg_ctl, aby ponownie załadować serwer.

Składnia byłaby następująca:

pg_ctl reload [-D datadir] [-s]

Aby dowiedzieć się, gdzie znajduje się Twój katalog danych, możesz wysłać zapytanie do systemu VIEW pg_settings, jeśli jesteś zalogowany jako SUPERUSER za pomocą podobnego zapytania SELECT, jak poniżej.

postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
           setting           
-----------------------------
 /var/lib/postgresql/10/main
(1 row)

Następnie przekaż swoją powłokę użytkownikowi postgres (lub innemu SUPERUSER) za pomocą:

$ sudo -u postgres bash

O ile nie dodałeś narzędzia pg_ctl do $PATH, musisz w pełni zakwalifikować go do użycia, a następnie przekazać polecenie do wykonania, wraz z lokalizacją datadir.

Oto przykład:

$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled

Sprawdźmy stan serwera za pomocą:

$ /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"

Przystępne dania na wynos

  • Role muszą spełniać wymagania zarówno z pliku pg_hba.conf, jak i uprawnień dostępu na poziomie bazy danych.
  • Plik pg_hba.conf jest sprawdzany od góry do dołu dla każdego żądania połączenia. Porządek w pliku jest istotny.

Uprawnienia i ograniczenia bazy danych, tabel i kolumn — dopasuj role do zadań i obowiązków

Aby role mogły korzystać z obiektów bazy danych (tabele, widoki, kolumny, funkcje itp.), muszą mieć przyznane im uprawnienia dostępu.

Polecenie GRANT definiuje te podstawowe uprawnienia.

Omówimy kilka przykładów, aby poznać istotę jego użycia.

Tworzenie baz danych

Ponieważ log_user otrzymał atrybuty CREATEDB i CREATEROLE, możemy użyć tej roli do stworzenia testowej bazy danych o nazwie trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Oprócz tworzenia nowej ROLI:

postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE

Na koniec log_user połączy się z nową bazą danych wersji próbnej:

postgres=> \c trial;
Password for user log_user: 
You are now connected to database "trial" as user "log_user".
trial=>

Zauważ, że znak zachęty zmienił się na nazwę „trial”, wskazując, że jesteśmy połączeni z tą bazą danych.

Wykorzystajmy log_user do TWORZENIA pozornej tabeli.

trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE

Rola log_user niedawno utworzyła rolę pomocnika, db_user. Wymagamy, aby db_user miał ograniczone uprawnienia do tabeli another_workload.

Niewątpliwie ta rola nie powinna mieć dostępu do kolumny sensitive_info. Polecenia INSERT, UPDATE i DELETE również nie powinny być wydawane w tym momencie, dopóki db_user nie spełni określonych oczekiwań.

Jednak db_user jest wymagany do wydawania zapytań SELECT. Jak możemy ograniczyć te role w tabeli another_workload?

Najpierw przeanalizujmy dokładną składnię znalezioną w dokumentacji poleceń GRANT PostgreSQL na poziomie tabeli.

GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]

Następnie wdrażamy wymagania określone dla roli db_user, stosując określoną składnię.

trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT

Zauważ, że zaraz po słowie kluczowym SELECT wymieniliśmy kolumny, do których db_user ma dostęp. Do czasu zmiany, jeśli db_user spróbuje wykonać zapytania SELECT w kolumnie sensitive_info lub jakiekolwiek inne polecenie w tym zakresie, zapytania te nie zostaną wykonane.

Po zalogowaniu się do użytkownika db_user zastosujemy to w praktyce, próbując wykonać zapytanie SELECT w celu zwrócenia wszystkich kolumn i rekordów z tabeli.

trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload

Kolumna sensitive_info jest uwzględniona w tym zapytaniu. Dlatego żadne rekordy nie są zwracane do db_user.

Ale db_user może WYBRAĆ dozwolone kolumny

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)

To działa dobrze.

Przetestujemy również polecenia INSERT, UPDATE i 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

Nie przypisując poleceń INSERT, UPDATE lub DELETE do użytkownika db_user, rola nie ma dostępu do ich używania.

Dzięki mnogości dostępnych opcji konfiguracja Twojej roli jest praktycznie nieograniczona. Możesz sprawić, by były w pełni funkcjonalne, zdolne do wykonywania dowolnych poleceń lub tak ograniczone, jak dyktują Twoje wymagania.

Przystępne dania na wynos

  • Role otrzymują uprawnienia dostępu do obiektów bazy danych za pomocą polecenia GRANT.
  • Obiekty bazy danych i polecenia przeciwko tym obiektom są wysoce konfigurowalne w środowisku PostgreSQL.

Zamykanie

Dzięki przykładom zamieszczonym w tym poście na blogu powinieneś lepiej zrozumieć:

  1. Tworzenie roli z określonymi atrybutami.
  2. Ustawianie działającego połączenia między klientem a serwerem, umożliwiającego logowanie ról do baz danych.
  3. Wysoce dostosuj swoje role, aby spełnić indywidualne wymagania dotyczące dostępu na poziomie bazy danych, tabeli i kolumny poprzez wdrożenie niezbędnych atrybutów.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak uzyskać dzień roku z daty w PostgreSQL?

  2. Ściągawka wydajnościowa dla PostgreSQL

  3. Całkowite ignorowanie stref czasowych w Rails i PostgreSQL

  4. Alternatywny format wyjściowy dla psql

  5. Postgres:WSTAW, jeśli jeszcze nie istnieje