Správa uživatelů v PostgreSQL může být složitá. Noví uživatelé jsou obvykle spravováni společně v několika klíčových oblastech prostředí. Oprávnění jsou často perfektní na jedné frontě, ale na druhé straně jsou nesprávně nakonfigurována. Tento blogový příspěvek poskytne praktické 'Tipy a triky' pro uživatele nebo role, jak je budeme znát, nastavení v PostgreSQL.
Oblasti, na které se zaměříme, jsou:
- Převzetí rolí PostgreSQL
Dozvíte se o rolích, atributech rolí, osvědčených postupech pro pojmenovávání rolí a běžných nastaveních rolí.
- Soubor pg_hba.conf
V této části se podíváme na jeden z klíčových souborů a jeho nastavení pro připojení na straně klienta a komunikaci se serverem.
- Oprávnění a omezení na úrovni databáze, tabulky a sloupce.
Chcete nakonfigurovat role pro optimální výkon a využití? Obsahují vaše tabulky citlivá data, ke kterým mají přístup pouze privilegované role? Přesto s potřebou umožnit různým rolím vykonávat omezenou práci? Tyto a další otázky budou uvedeny v této sekci.
Převzetí rolí PostgreSQL – Co je to „Role“ a jak ji vytvořit?
Oprávnění pro přístup k databázi v rámci PostgreSQL jsou řešena konceptem role, která je podobná uživateli. Role mohou také představovat skupiny uživatelů v ekosystému PostgreSQL.
PostgreSQL vytváří kapacitu pro role přidělovat oprávnění k databázovým objektům, které vlastní, a umožňuje tak přístup a akce k těmto objektům. Role mají možnost udělit členství jiné roli. Atributy poskytují možnosti přizpůsobení pro povolené ověření klienta.
Atributy pro role prostřednictvím příkazu CREATE ROLE jsou dostupné v oficiální dokumentaci PostgreSQL.
Níže jsou uvedeny atributy, které běžně přiřadíte při nastavování nové role. Většina z nich je samovysvětlující. K objasnění případných nejasností je však uveden stručný popis spolu s příklady použití.
SUPERUSER - Databáze SUPERUSER si zaslouží upozornění. Sečteno a podtrženo, role s tímto atributem mohou vytvořit dalšího SUPERUSER. Ve skutečnosti je tento atribut vyžadován k vytvoření další role SUPERUSER. Protože role s tímto atributem obcházejí všechny kontroly oprávnění, udělujte toto oprávnění uvážlivě.
CREATEDB – Umožňuje roli vytvářet databáze.
CREATEROLE - S tímto atributem může role zadat příkaz CREATE ROLE. Vytvořte si proto další role.
PŘIHLÁSIT - Umožňuje přihlášení. Název role s tímto atributem lze použít v příkazu pro připojení klienta. Další podrobnosti o tomto atributu s připravovanými příklady.
Některé atributy mají explicitní polární opačný pojmenovaný příkaz a obvykle je výchozí, pokud nejsou specifikovány.
např.
SUPERUSER | NOSUPERUSER
CREATEROLE |NOCREATEROLE
PŘIHLÁŠENÍ |NOLOGIN
Podívejme se na některé z těchto atributů v akci pro různé konfigurace, které můžete nastavit, abyste mohli začít.
Vytváření a rušení rolí
Vytvoření role je poměrně jednoduché. Zde je rychlý příklad:
postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;
Co se tam pokazilo? Ukázalo se, že názvy rolí nemohou začínat ničím jiným než písmenem.
"Co takhle zabalit jméno do uvozovek?" Podívejme se:
postgres=# CREATE ROLE "$money_man";
CREATE ROLE
To fungovalo, i když to asi nebyl dobrý nápad. Co takhle speciální znak uprostřed jména?
postgres=# CREATE ROLE money$_man;
CREATE ROLE
Žádný problém. Ani bez dvojitých uvozovek nebyla vrácena žádná chyba.
Jen nemám rád strukturu jména $money_man pro uživatele. Nechám vás $money_man a začnu znovu. O odebrání role se stará příkaz DROP ROLE. Tady se to používá.
postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;
A další chyba s rolí $money_man. Opět se uchyluji k dvojitým uvozovkám.
postgres=# DROP ROLE "$money_man";
DROP ROLE
Oprávnění PŘIHLÁSIT
Podívejme se na dva různé uživatele, jednoho s oprávněním PŘIHLÁSIT a druhého bez něj. Přidělím jim také hesla.
postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE
Poznámka:Hesla poskytnutá výše uvedeným fiktivním rolím jsou pouze pro demonstrační účely. Při implementaci rolí byste se měli vždy snažit poskytovat jedinečná a tvrzená hesla. Zatímco heslo je lepší než žádné heslo, zpevněné heslo je ještě lepší než triviální.
Přiřaďme log_user atributy CREATEDB a CREATEROLE pomocí příkazu ALTER ROLE.
postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE
Tyto atributy sady můžete ověřit kontrolou katalogu pg_role. Dva zajímavé sloupce jsou rolcreaterol a rolcreatedb. Oba jsou datového typu Boolean, takže pro tyto atributy by měly být nastaveny na t jako true.
Potvrďte podobným dotazem SELECT.
postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb
---------------+-------------
t | t
(1 row)
Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper Jak můžete určit existující role přítomné v databázi?
Dvě dostupné metody jsou příkaz psql \du nebo výběr z katalogu pg_roles.
Zde se oba používají.
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)
Přihlášení
Dejme oběma rolím příležitost přihlásit se k serveru.
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
Abychom tento problém vyřešili, musíme se ponořit do souboru pg_hba.conf. Řešení je diskutováno, jak pokračujeme v tomto příspěvku k této konkrétní sekci.
Akční výsledky
- CREATE ROLE a její protějšek, DROP ROLE, jsou vaše hlavní příkazy pro implementaci a odebrání rolí.
- ALTER ROLE se stará o změnu atributů role.
- Role jsou platné ve všech databázích kvůli definici na úrovni databázového clusteru.
- Mějte na paměti, že vytvoření názvu role začínajícího speciálním znakem vyžaduje, abyste jej „adresovali“ dvojitými uvozovkami.
- Role a jejich oprávnění jsou stanoveny pomocí atributů.
- Chcete-li vytvořit role, které ve výchozím nastavení potřebují atribut LOGIN, CREATE USER je volitelný příkaz, který máte k dispozici. Používají se místo CREATE ROLE role_name LOGIN a jsou v podstatě stejné.
Soubor pg_hba.conf – vytvoření společného základu mezi serverem a klientem
Pokrýt všechny aspekty a nastavení pro soubor pg_hba.conf v jednom příspěvku na blogu by bylo přinejlepším skličující. Místo toho tato část představí běžné nástrahy, se kterými se můžete setkat, a řešení, jak je napravit.
Úspěšná spojení vyžadují společné úsilí obou částí jako celku. Role připojující se k serveru musí po předání nastavení v souboru pg_hba.conf stále splňovat omezení přístupu nastavená na úrovni databáze.
Relevantní příklady tohoto vztahu jsou zahrnuty v průběhu této části.
Chcete-li najít svůj soubor pg_hba.conf, zadejte podobný dotaz SELECT v VIEW pg_settings. Pro dotaz na toto ZOBRAZENÍ musíte být přihlášeni 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)
Soubor pg_hba.conf obsahuje záznamy určující jeden ze sedmi dostupných formátů pro daný požadavek na připojení. Podívejte se na celé spektrum zde.
Pro účely tohoto blogového příspěvku se podíváme na nastavení, která můžete použít pro místní prostředí.
Možná je tento server pro vaše další učení a studium (jako můj).
Musím zvlášť poznamenat, že tato nastavení nejsou optimálním nastavením pro opevněný systém obsahující více uživatelů.
Pole pro tento typ připojení jsou:
local database user auth-method [auth-options]
Kde znamenají:
local - pokus o připojení pomocí soketů unixové domény.
databáze – Určuje databáze pojmenované pro tento záznam.
uživatel - Jméno uživatele databáze odpovídající tomuto záznamu. Pro toto pole je také povolen seznam více uživatelů nebo všech oddělených čárkami.
auth-method – používá se, když připojení odpovídá tomuto jedinečnému záznamu. Možné volby pro toto pole jsou:
- důvěřovat
- odmítnout
- scram-sha-256
- md5
- heslo
- gss
- sspi
- ident
- rovný
- ldap
- poloměr
- certifikát
- pam
- bsd
Řádky nastavené v souboru pg_hba.conf pro role nolog_user a log_user vypadají takto:
local all nolog_user password
local all log_user password
Poznámka:Protože je heslo zasíláno jako prostý text, nemělo by se používat v nedůvěryhodných prostředích s nedůvěryhodnými sítěmi.
Podívejme se na tři zajímavé sloupce z ZOBRAZENÍ pg_hba_file_rules pomocí níže uvedeného dotazu. Vaše role opět potřebuje atribut SUPERUSER k dotazování na toto ZOBRAZENÍ.
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)
Z výše uvedených řádků v souboru pg_hba.conf můžeme vidět stejné informace jako z doprovodného dotazu. Na první pohled to vypadá, že se obě role mohou přihlásit.
Otestujeme a potvrdíme.
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=>
Klíčovým bodem je, že i když se nolog_user a log_user mohou přihlásit podle souboru pg_hba.conf, pouze log_user se může skutečně přihlásit.
Tam, kde log_user splnil omezení přístupu na úrovni databáze (tím, že měl atribut LOGIN), nolog_user nikoli.
Upravme řádek log_user v souboru pg_hba.conf a změňme název databáze, ke které má tato role přístup. Zde je změna, která naznačuje, že log_user se nyní může přihlásit pouze do zkušební databáze.
local trial log_user password
Nejprve se zkusme přihlásit do postgres databáze, ke které měl log_user dříve přístup díky příznaku 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
Nyní se zkušební databází log_user má oprávnění k
$ psql -U log_user -W trial
Password for user log_user:
psql (10.1)
Type "help" for help.
trial=>
Žádná chyba a výzva trial=> ukazuje aktuálně připojenou databázi.
Tato nastavení platí také v prostředí serveru, jakmile je navázáno spojení.
Zkusme se znovu připojit k této postgresové databázi:
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
Prostřednictvím zde uvedených příkladů byste si měli být vědomi možností přizpůsobení pro role ve vašem clusteru.
Poznámka:Aby se změny projevily, je často nutné znovu načíst soubor pg_hba.conf.
K opětovnému načtení serveru použijte nástroj pg_ctl.
Syntaxe by byla:
pg_ctl reload [-D datadir] [-s]
Chcete-li vědět, kde je váš datový adresář, můžete se dotázat na systém pg_settings VIEW, pokud jste přihlášeni jako SUPERUSER, pomocí podobného dotazu SELECT jako níže.
postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
setting
-----------------------------
/var/lib/postgresql/10/main
(1 row)
Poté dejte svůj shell uživateli postgresu (nebo jinému SUPERUSER) s:
$ sudo -u postgres bash
Pokud jste do své $PATH nepřidali obslužný program pg_ctl, musíte jej plně kvalifikovat k použití a poté předat příkaz k provedení spolu s umístěním datadir.
Zde je příklad:
$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled
Pojďme zkontrolovat stav serveru 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"
Akční výsledky
- Role musí splňovat požadavky jak ze souboru pg_hba.conf, tak z přístupových práv na úrovni databáze.
- Soubor pg_hba.conf se kontroluje shora dolů pro každý požadavek na připojení. Pořadí v souboru je významné.
Oprávnění a omezení pro databáze, tabulky a sloupce – přizpůsobení rolí pro úkoly a odpovědnosti
Aby role mohly používat databázové objekty (tabulky, pohledy, sloupce, funkce atd...), musí jim být udělena přístupová práva.
Příkaz GRANT definuje tato základní oprávnění.
Projdeme si několik příkladů, abychom získali podstatu jeho použití.
Vytváření databází
Protože log_user byly přiděleny atributy CREATEDB a CREATEROLE, můžeme tuto roli použít k vytvoření testovací databáze s názvem trial.
postgres=> CREATE DATABASE trial:
CREATE DATABASE
Kromě vytvoření nové ROLE:
postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE
Nakonec se log_user připojí k nové zkušební databázi:
postgres=> \c trial;
Password for user log_user:
You are now connected to database "trial" as user "log_user".
trial=>
Všimněte si, že se výzva změnila na název 'trial', což znamená, že jsme připojeni k dané databázi.
Využijme log_user k VYTVOŘENÍ falešné tabulky.
trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE
Role log_user nedávno vytvořila pomocnou roli db_user. Požadujeme, aby měl db_user omezená oprávnění pro tabulku other_workload.
Tato role by bezpochyby neměla mít přístup ke sloupci sensitive_info. Příkazy INSERT, UPDATE a DELETE by v tuto chvíli také neměly být udělovány, dokud db_user nesplní určitá očekávání.
K zadání SELECT dotazů je však vyžadován db_user. Jak můžeme omezit schopnosti těchto rolí v tabulce other_workload?
Nejprve se podívejme na přesnou syntaxi, kterou naleznete v dokumentech příkazu PostgreSQL GRANT na úrovni tabulky.
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
Dále implementujeme požadavky stanovené pro roli db_user s použitím specifické syntaxe.
trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT
Všimněte si, že hned za klíčovým slovem SELECT jsme uvedli sloupce, ke kterým má db_user přístup. Pokud se db_user pokusí o SELECT dotazy na sloupec sensitive_info nebo jakýkoli jiný příkaz, nebudou tyto dotazy provedeny, dokud se to nezmění.
S přihlášeným db_user to zavedeme do praxe a pokusíme se SELECT dotaz vrátit všechny sloupce a záznamy z tabulky.
trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload
Tento dotaz obsahuje sloupec sensitive_info. Proto nejsou db_user vráceny žádné záznamy.
Ale db_user může VYBRAT povolené sloupce
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 funguje dobře.
Otestujeme také příkazy INSERT, UPDATE a 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
Tím, že db_user nepřiřadíte příkazy INSERT, UPDATE nebo DELETE, je této roli odepřen přístup k jejich používání.
Díky velkému množství dostupných možností je konfigurace vaší role prakticky neomezená. Můžete je vytvořit plně funkční, schopné provádět jakýkoli příkaz nebo mohou být omezeny podle vašich požadavků.
Akční výsledky
- Role jsou poskytovány přístupová oprávnění k databázovým objektům prostřednictvím příkazu GRANT.
- Databázové objekty a příkazy proti těmto objektům jsou vysoce konfigurovatelné v prostředí PostgreSQL.
Zavírání
Prostřednictvím příkladů uvedených v tomto příspěvku na blogu byste měli lépe porozumět:
- Vytvoření role se specifickými atributy.
- Nastavení funkčního připojení mezi klientem a serverem, které umožní rolím přihlášení k databázím.
- Vysoce přizpůsobte své role tak, aby splňovaly individuální požadavky na přístup na úrovni databáze, tabulky a sloupce implementací nezbytných atributů.