db.dobo.sk

Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 11. Users and roles.

bez komentára

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.

píše: ďobo

September 17th, 2020 o 2:24 pm

chlievik: postgresql

okomentuj