PostgreSQL nabízí několik různých metod ověřování klientů a tentokrát si ukážeme, jak nastavit ověřování pomocí metody GSSAPI, která se obvykle používá pro přístup k Microsoft Active Directory nebo FreeIPA.
Základní požadavky
Zde je výčet základních požadavků pro funkční nastavení ověřování uživatelů z Active Directory v PostgreSQL pomocí Kerberos (GSS):
- nainstalovaný server PostgreSQL
- nainstalovou podporu a nastavení pro Kerberos na DB serveru
- uživatelský účet v Active Directory pro PostgreSQL
- vytvořený Kerberos keytab pro uživatele v Active Directory
- nastavený PostgreSQL pro Kerberos a GSSAPI
- uživatelský účet v PostgreSQL totožný s účtem v Active Directory (nebo ldap2pg)
- ověřovací Kerberos ticket pro DB uživatele v Active Directory
Instalace a konfigurace Kerberos
Nejprve na databázovém serveru nainstalujeme základní balíčky, které obsahují knihovny, a binární i konfigurační soubory pro podporu Kerberos.
dnf install krb5-server krb5-workstation
V případě, že chceme používat k autentizaci Kerberos i na samotném klientu (potažmo serveru), je potřeba mít zde i správně nastavený Kerberos.
Ovšem PostgreSQL samotný toto nastavení pro funkční ověřování uživatelů nepotřebuje.
Kerberos se na úrovni OS nastavuje v konfiguračním souboru /etc/krb5.conf
a tento soubor může upravovat pouze privilegovaný uživatel root
.
Vzorová konfigurace může kupříkladu vypadat následovně:
[logging]
default = /var/log/krb5libs.log
kdc = /var/log/krb5kdc.log
admin_server = /var/log/kadmind.log
[libdefaults]
default_realm = DEMO.INITMAX.CZ
dns_lookup_realm = false
# ticket_lifetime = 24h
# renew_lifetime = 7d
forwardable = true
udp_preference_limit = 1
default_ccache_name = KEYRING:persistent:%{uid}
[realms]
DEMO.INITMAX.CZ = {
kdc = demo.initmax.cz
admin_server = demo.initmax.cz
}
[domain_realm]
.demo.initmax.cz = DEMO.INITMAX.CZ
demo.initmax.cz = DEMO.INITMAX.CZ
Uživatelský účet v Active Directory
Na úrovni Active Directory běžným způsobem vytvoříme servisní účet, který v našem případě nazveme pg_db_srv01
.
A následně vytvoříme níže zobrazeným příkazem tzv. Kerberos keytab, který k tomuto servisnímu účtu přiřadíme.
ktpass –princ POSTGRES/pgsql.demo.initmax.cz@DEMO.INITMAX.CZ -pass %heslo% -mapuser pg_db_srv01 -crypto ALL -ptype KRB5_NT_Principal -out pgsql.demo.initmax.cz.keytab
Takto vzniklý Kerberos keytab si zkopírujeme a přesuneme ho na klienta, v našem případě tedy na databázový server, například do složky /etc
.
Přímo na databázovém serveru si pak můžeme ověřit, že vytvořený keytab skutečně funguje, a to následujícím příkazem:
kinit -k -t /etc/pgsql.demo.initmax.cz.keytab POSTGRES/pgsql.demo.initmax.cz@DEMO.INITMAX.CZ -V
Pokud nám příkaz kinit
na konci svého běhu ve výstupu zobrazí hlášku Authenticated to Kerberos
, pak je keytab funkční a my můžeme překročit ke konfiguraci samotného PostgreSQL.
Vzorový výstup výše zmíněného příkazu kinit
s funkčním souborem keytab můžete vidět zde:
Using existing cache: 0
Using principal: POSTGRES/pgsql.demo.initmax.cz@DEMO.INITMAX.CZ
Using keytab: /etc/pgsql.demo.initmax.cz.keytab
Authenticated to Kerberos v5
Konfigurace PostgreSQL
Nejprve upravíme konfigurační soubor PostgreSQL (postgresql.conf
) tak, aby věděl, kde mu leží náš Kerberos keytab a tudíž ho korektně načetl a použil.
K tomu slouží následující konfigurační direktiva krb_server_keyfile
, jejíž hodnotu naplníme absolutní cestou ke Kerberos keytabu.
V našem případě tedy /etc/pgsql.demo.initmax.cz.keytab
.
krb_server_keyfile=/etc/pgsql.demo.initmax.cz.keytab
Následně v konfiguračním souboru nastavujícím přístupy, tedy pg_hba.conf
povolíme lokální i vzdálené ověřování pomocí metody GSSAPI se správně nastaveným Kerberos realm.
# IPv4 local connections:
#host all all 127.0.0.1/32 ident
host all all 0.0.0.0/0 gss include_realm=0 krb_realm=DEMO.INITMAX.CZ
Poté se připojíme k serveru pomocí psql
a vytvoříme uživatele na úrovní samotného PostgreSQL a nastavíme mu požadováná oprávnění.
Pozor! Tento uživatel musí odpovídat skutečnému uživatli v Active Directory!
create user "ad_user" superuser;
Jako další krok můžeme konzoli psql opustit a příkazem kinit
získáme (po zadání správného hesla) ověřovací ticket pro našeho uživatele z Active Directory serveru:
kinit ad_user
A v tuto chvíli se již pod tímto uživatelem můžeme přihlásit přímo do PostgreSQL bez nutnosti zadání hesla, jelikož se pro ověření použije ticket, získaný výše.
psql -U "ad_user" -h csas-pgsql.win.initmax.cz postgres
Nespornou nevýhodou tohoto nativního řešení pak (v závislosti na velikosti prostředí) zůstává nutnost uživatele ručně vytvářet na úrovni PostgreSQL.
Tyto činnosti je však možné zautomatizovat, a to pomocí ldap2pg
, na což se podíváme v následující kapitole.
ldap2pg
Toto je nástroj, který na základě předem nastavených parametrů automatizuje vytváření, aktualizaci i odebírání rolí na PostgreSQL podle nastavení v LDAP.
ldap2pg je skript napsaný v jazyku Python, a pro svůj běh vyžaduje kromě Pythonu samotného (v2.6+ nebo v3.4+) i další závislé balíčky.
Konkrétně to jsou Pyyaml
, python-ldap
a python-psycopg2
.
Instalace
Doporučovaná metoda instalace je v případě RHEL přímo z oficiálního repozitáře PostgreSQL (PGDG) a v případě Debian pak pomocí pip
.
Pokud chceme balíčky co nejaktuálnější, pak využijeme přímo repozitář Dalibo labs.
V našem případě používáme Rocky Linux 9 a tudíž si oficiální repozitář Dalibo labs přidáme následujícím příkazem a následně obnovíme dnf
cache.
dnf install -y https://yum.dalibo.org/labs/dalibo-labs-4-1.noarch.rpm
dnf makecache fast
Další možností je vytvoření repozitáře ručně. To uděláme tak, že vytvoříme nový soubor /etc/yum.repos.d/dalibolabs.repo a ten naplníme následujícím obsahem:
[dalibolabs]
name = Dalibo Labs - RHEL/CentOS/Rockylinux $releasever - $basearch
baseurl = https://yum.dalibo.org/labs/RHEL$releasever-$basearch
gpgcheck = 1
enabled = 1
Soubor uložíme a zaktualizujeme dnf
cache:
dnf makecache fast
Potom, co máme přidaný repozitář, můžeme přejít k samotné instalaci ldap2pg a všech jeho závislostí:
dnf install ldap2pg
Jakmile máme ldap2pg úspěšně nainstalován, tak můžeme překročit k jeho konfiguraci.
Nastavení
ldap2pg standardně vyhledává svůj konfigurační soubor v těchto cestách:
- ldap2pg.yml v aktuálním pracovním adresáři
- ~/.config/ldap2pg.yml
- /etc/ldap2pg.yml
Lze však nastavit i cestu vlastní a to spuštění ldap2pg s parametrem --config
, toto lze využít například pro spuštění několika instancí ldap2pg
s různými konfiguračními soubory.
Zde můžete pro ukázku vidět příklad takové konfigurace:
postgres:
dsn: postgres://alfa@csas-pgsql.win.initmax.cz:5432/postgres
roles_blacklist_query:
- postgres
- "pg_*"
- "rds_*"
ldap:
uri: ldap://dc1.win.initmax.cz
binddn: CN=Test User Alfa,OU=Users,OU=testAcounts,DC=win,DC=initmax,DC=cz
password: "%heslo%"
sync_map:
- role:
name: alfa
options: LOGIN SUPERUSER
names:
- ad_roles
comment: "LDAP role managed by ldap2pg."
- ldapsearch:
base: CN=pg_DBA_users,OU=Groups,OU=testAcounts,DC=win,DC=initmax,DC=cz
role:
name: 'dba_{member.samaccountname}'
options: LOGIN SUPERUSER
parent: ad_roles
comment: "Synced from AD: {dn}"
- ldapsearch:
base: CN=pg_RO_users,OU=Groups,OU=testAcounts,DC=win,DC=initmax,DC=cz
role:
name: '{member.samaccountname}'
options: LOGIN
parent: ad_roles
comment: "Synced from AD: {dn}"
Tento ukázkový konfigurační soubor obsahuje několik částí.
V části postgres:
definujeme připojení k databázovému serveru a k databázi, včetně přihlašovacích údajů. Z bezpečnostních důvodů doporučujeme přihlašovací heslo v konfiguračním souboru nepoužívat, ale namísto toho uživatele ověřovat přes Kerberos ticket, jak je ukázáno právě v tomto návodu. Součástí této sekce je i direktiva roles_blacklist_query:
nám určuje seznam lokálních rolí v PostgreSQL, které bude ldap2pg ignorovat. Povšimněte si možnosti využití zástupných znaků.
V části ldap:
definujeme připojení k Active Directory, nebo jinému LDAP serveru. Tato sekce je v tomto konfiguračním souboru volitelná a informace o nastavení LDAP si nástroj ldap2pg
umí načíst i z jakéhokoliv standardního umístění těchto systémových konfiguračních souborů (např. /etc/ldap.conf
), kde je záhodno mít případně uloženo i heslo pro bind uživatel v LDAP.
Poslední sekci sync_map:
pak používáme k mapování uživatelů a rolí. Na jejím začátku definujeme příklad lokální, statické role pro admin uživatele „alfa“ s právém přihlásit se a rolí SUPER USER
. Zároveň v této sekci vytváříme uživatelskou roli ad_roles
, do které následně přiřazujeme další, automaticky vytvořené uživatele pomocí ldap2pg (a této roli je vytvořen i takto formulovaný komentář). V podsekcích ldapsearch:
pak definujeme jednotlivá BaseDN
, tedy cesty ve struktuře LDAP, kde má ldap2pg
uživatele hledat. Vzorově zde vytváříme databázové administrátory (ze skupiny pg_DBA_users
) a uživatele pro čtení (ze skupiny pg_RO_users
) s jejich příslušnými oprávěními a komentáři. Jako nadřazenou roli mají ad_roles
, kterou jsme si definovali v předchozí podsekci.
Testování a spuštění
Nespornou výhodou nástoje ldap2pg
je rovněž možnost si vytvořené nastavení nanečisto otestovat (tzv. dry run), a to pomocí spouštěcího parametru --dry
, jehož výstup s naší vzorovou konfigurací můžete vidět zde:
Starting ldap2pg 5.8.
Using /root/ldap2pg.yml.
Connecting to LDAP server ldap://dc1.win.initmax.cz.
Trying simple bind.
Running in dry mode. Postgres will be untouched.
Inspecting roles in Postgres cluster...
Querying LDAP CN=pg_DBA_users,OU=Group... (objectClass...
Missing 'member' from CN=pg_DBA_users,OU=Groups,OU=testAcounts,DC=win,DC=initmax,DC=cz.
Considering it as an empty list.
Querying LDAP CN=pg_RO_users,OU=Groups... (objectClass...
Missing 'member' from CN=pg_RO_users,OU=Groups,OU=testAcounts,DC=win,DC=initmax,DC=cz. Considering
it as an empty list.
Nothing to do.
Comparison complete.
V případě, že test proběhl úspěšně, pak ldap2pg
spustíme s parametrem --real
, který už námi otestovanou konfiguraci přímo projeví konkrétními změnami v PostgreSQL.
Pro tento příkaz pak stačí už jen vytvořit pravidelně spouštěnou úlohu, například pomocí cron
.
ldap2pg --real
V tuto chvíli tak máme funkční ověřování uživatelů do PostgreSQL pomocí Kerberos, včetně automatizace jejich správy z údajů v Active Directory, a to pomocí nástroje ldap2pg.
Dejte nám Like, sdílejte nás nebo nás sledujte 😍
Ať vám nic neunikne: