Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 11. Users and roles.
Narozdiel od obecneho zvyku rozdelovat pristupy medzi userov a grupy (roly) a la Oracle, postgres to ma jednoduche: v zasade existuje len rola (ROLE), ktora moze byt zapuzdrovana do inych roli. Prikaz CREATE USER a CREATE GROUP su len aliasom ku komandu CREATE ROLE. Malym rozdielom je, ze v pripade CREATE USER je uzivatel vytvoreny automaticky s privilegiom LOGIN, zatailco u CREATE ROLE nie. Konzekventne prikaz SELECT * FROM PG_USER; ukaze len userov, ktori sa mozu lognut, zatialco SELECT * FROM PG_ROLES; ukaze absolutne vsetkych userov.
Inymi sposobmi na listovanie userov je psql \du+ a SELECT * FROM PG_SHADOW;
Ak chceme vyuzivat princip grup, tak je nutne vytvorit rolu, ktora bude zapuzdrovat userov:
- CREATE ROLE grp_admins INHERIT;
- CREATE ROLE franta;
- GRANT grp_admins TO franta;
Bez inherit by samozrejme zapuzdrovala, ale user by nezdedil opravnenia grupy.
roly a systemovy katalog
Pre roly su podstatne tieto objekty z pg_catalog:
pg_authid —-> zakladny zoznam roli, ich atributov a zahashovany password
pg_roles —-> je len systemovy view nad tabulkou pg_authid, maskuje hash passwordu
pg_auth_members —-> definuje zapuzdrenie roli do roli (member of…)
pg_ident a pg_hba
Tieto dva konfiguraky upravuju obecny pristup k celemu DB clusteru. pg_ident.conf mapuje system userov na db userov, napr.:
MAPNAME SYSTEM-USERNAME PG-USERNAME
local_admins root postgres
Znamena, root sa bude mapovat na postgres premennou local_admins
pg_hba.conf ma vlastnu syntax, a roota v predchadzajucom pripade autmaticky namapujeme na postgres nasledovne:
TYPE DATABASE USER ADDRESS METHOD
local all postgres peer map=local_admins
Inak zaznam v hba.confe pre LDAP ma takuto syntax:
host all all “allowed IP” ldap ldapserver=192.168.1.1 ldapbasedn=”cn=users,dc=example,dc=com” ldapbindpasswd=”password” ldapsearchattribute=””
hesla a hashe
Do verzie 10 sa pouzivali pre storovanie DB hesiel 2 metody: plaintext (vyzadovany napr. LDAPom) a md5 (+SSL/TLS). Obe metody su heknutelne odposluchom, alebo dumpom databazy.
Aktualne (ver. 10 – 15) sa pouziva hlavne md5 (Irenko, proc?) a SCRAM-SHA-256 . Hash hesla sa uklada do pg_authid (na aws standarne nedostupne!!!).
Ako funguje hashovanie pomocou md5? Ako salt sa pouziva username (rolname) a na vysledny string sa prida na zaciatok retazec md5, ergo rolpassword=(‘md5’||md5(passwords || rolname)); Ma to jednu zaujimavu konzekvenciu, pretoze ak niekto pouzije heslo rovnake, ako username, da sa na to prist :) :
SELECT *
FROM pg_authid
WHERE rolpassword=(‘md5’||md5(rolname||rolname));
co nas mimochodom privadza k passwordchecku….
passwordcheck
paswordcheck je modul instalovany s balikom postgresql-contrib. Na jeho inicializaciu ho staci zaradit v konfe do shared_preload_libraries. Co robi? V zasade 2 veci (vid source):
- pri zadavani hesla kontroluje jeho silu (8 znakov atd…)
- snazi sa odhadnut silu stavajucich hesiel. Kedze tie su zahashovane, tak moc priestoru na to nema. Pomocou vyssie uvedej rutiny kontroluje, ci pre password nebolo pouzite meno usera
male triky
- pokial zabudnes heslo pre rolu postgres a nemas trust medzi rootom a postgresom, tak si vyedituj pg_hba.conf a zmen md5 na trust, po prihlaseni ALTER ROLE postgres…
- Je lepsie pouzivat \password na psql konzole, nez ALTER USER xyz WITH PASSWORD ‘abcd’; V prvom pripade totiz novy password nie je v historii psql konzoly.
privileges a default privileges
Mať role je veľký pekný, ale pokiaľ role nemajú privileges, tak sú k ničomu. V postgrese je tomu tak, že všetko nad objektom (akýmkoľvek) môže superuser (postgres) a owner (ten, kto objekt, napr. tabuľku vytvoril). Všetci ostatní musia mať privileges buď explicitne nagrantované, alebo podedené z default privileges.
\dp = vylistuje privileges
\ddp = vylistuje default privileges
Pri vylistovaní su privileges ukázané akronymom podobným ako ACL a za lomítkom je uvedený grantor. Zoznam privileges a “ACL” akronym k tomu sú v tejto dobrej prehľadnej tabuľke.
Default privileges su oprávnenia, ktoré budú aplikovať v budúcnosti a dajú sa aplikovať per schéma.
efective privileges pre konkrétneho usera
Najčastejšou otázkou je, aké aktuálne privileges má konkrétny user. Je možné sa pýtať dvoma spůsobmi:
a) spýtať sa na konkrétne privilege pre konkrétneho usera nad konkrétnym objektom pomocou funkcií “has privilege”, ktoré vracajú boolovskú hodnotu, napr:
SELECT has_table_privilege('dobo', 'mytable', 'INSERT, SELECT');
b) nechať si vylistovať agregovane userov a privileges za pomocu custom dotazu:
SELECT r.rolname AS user_name,
c.oid::regclass AS table_name,
p.perm AS privilege_type
FROM pg_class c CROSS JOIN
pg_roles r CROSS JOIN
unnest(ARRAY['SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER']) p(perm)
WHERE relkind = 'r' AND
relnamespace NOT IN (SELECT oid FROM pg_namespace WHERE nspname in ('pg_catalog','information_schema')) AND
has_table_privilege(rolname, c.oid, p.perm) AND rolname = '$USER' AND relname = '$TABLE';
drop role
Drop role je jednoducha zalezitost, pokial ovsem nie je vlastnikom nejakych objektov. V tom pripade drop zlyha. Je nutne objekty naleziace likvidovanej roli najprv preasignovat na inu rolu, alebo dropnut najprv objekty. (REASSIGN OWNED, DROP OWNED).
Jak vyzistit objekty, ktore patria nejakej roli? Pomocou tohto SQL skriptu.
default roles po instalacii vanilla posgresu
Po standarnom nainstalovani binariek a initdb su v postgres clusteru vytvorene default role (grupy) na zakladnu spravu, okrem superusera postgres. Ake su to?
Privilegia nad funkciami
Niekedy je dobre zistit, kto ma privilegia pre run funkcie:
SELECT proname, proacl from pg_proc where proname=’NAZOV_FUNKCIE’;
REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;
dobo
15 Jul 24 at 10:36
Najpodrobnejsia rozprava o roles a privileges jednoznacne tato prezentacia:
https://thebuild.com/presentations/cyp.pdf
ďobo
19 Jul 24 at 14:13