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.

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 nedostupna!!!).

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):

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);

píše: ďobo

September 17th, 2020 o 2:24 pm

chlievik: postgresql

okomentuj