PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Privilegi PostgreSQL e gestione degli utenti:cosa dovresti sapere

La gestione degli utenti all'interno di PostgreSQL può essere complicata. In genere i nuovi utenti vengono gestiti, di concerto, all'interno di un paio di aree chiave dell'ambiente. Spesso i privilegi sono perfetti su un fronte, ma configurati in modo errato sull'altro. Questo post del blog fornirà pratici "Suggerimenti e trucchi" per un utente o un ruolo, come lo scopriremo, configurato all'interno di PostgreSQL.

Le aree tematiche su cui ci concentreremo sono:

  • Il ruolo di PostgreSQL

Imparerai a conoscere i ruoli, gli attributi dei ruoli, le best practice per la denominazione dei ruoli e le impostazioni comuni dei ruoli.

  • Il file pg_hba.conf

In questa sezione esamineremo uno dei file chiave e le sue impostazioni, per le connessioni lato client e la comunicazione con il server.

  • Privilegi e restrizioni a livello di database, tabella e colonna.

Stai cercando di configurare i ruoli per prestazioni e utilizzo ottimali? Le tue tabelle contengono dati sensibili, accessibili solo ai ruoli privilegiati? Eppure con la necessità di consentire a ruoli diversi di svolgere un lavoro limitato? Queste e altre domande verranno esposte in questa sezione.

Assunzione di ruoli di PostgreSQL:cos'è un "ruolo" e come crearne uno?

Le autorizzazioni per l'accesso al database all'interno di PostgreSQL sono gestite con il concetto di ruolo, che è simile a un utente. I ruoli possono rappresentare anche gruppi di utenti nell'ecosistema PostgreSQL.

PostgreSQL stabilisce la capacità dei ruoli di assegnare privilegi agli oggetti di database di loro proprietà, consentendo l'accesso e le azioni a tali oggetti. I ruoli hanno la possibilità di concedere l'appartenenza a un altro ruolo. Gli attributi forniscono opzioni di personalizzazione, per l'autenticazione client consentita.

Gli attributi per i ruoli tramite il comando CREATE ROLE sono disponibili nella documentazione ufficiale di PostgreSQL.

Di seguito sono riportati gli attributi che assegnerai comunemente durante l'impostazione di un nuovo ruolo. La maggior parte di questi sono autoesplicativi. Tuttavia, viene fornita una breve descrizione per chiarire qualsiasi confusione insieme agli usi di esempio.

SUPERUSER - Un database SUPERUSER merita una parola di cautela. In conclusione, i ruoli con questo attributo possono creare un altro SUPERUSER. In realtà, questo attributo è necessario per creare un altro ruolo SUPERUSER. Poiché i ruoli con questo attributo ignorano tutti i controlli di autorizzazione, concedi questo privilegio con giudizio.

CREATEDB - Consente al ruolo di creare database.

CREATEROLE - Con questo attributo, un ruolo può emettere il comando CREATE ROLE. Quindi, crea altri ruoli.

LOGIN - Abilita la possibilità di accedere. Un nome di ruolo con questo attributo può essere utilizzato nel comando di connessione client. Maggiori dettagli su questo attributo con prossimi esempi.

Alcuni attributi hanno un comando esplicito con nome polare opposto e in genere è l'impostazione predefinita quando non viene specificato.

es.
SUPERUSER | NOSUPERUSER
CREATEROLO |NOCREATEROLE
LOGIN |NOLOGIN

Diamo un'occhiata ad alcuni di questi attributi in azione per varie configurazioni che puoi impostare per iniziare.

Creazione e rilascio di ruoli

Creare un ruolo è relativamente semplice. Ecco un rapido esempio:

postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;

Cosa è andato storto lì? Si scopre che i nomi dei ruoli non possono iniziare con nient'altro che una lettera.

"Che ne dici di racchiudere il nome tra virgolette?" Vediamo:

postgres=# CREATE ROLE "$money_man";
CREATE ROLE

Ha funzionato, anche se probabilmente non è una buona idea. Che ne dici di un carattere speciale nel mezzo del nome?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Nessun problema lì. Anche senza virgolette, non è stato restituito alcun errore.

Semplicemente non mi piace la struttura del nome di $money_man per un utente. Ti lascio $money_man e ricomincio da capo. Il comando DROP ROLE si occupa della rimozione di un ruolo. Eccolo in uso.

postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;

E un altro errore con il ruolo $money_man. Anche in questo caso, ricorrendo alle virgolette lo è.

postgres=# DROP ROLE "$money_man";
DROP ROLE

Il privilegio LOGIN

Diamo un'occhiata a due diversi utenti, uno con il privilegio LOGIN e uno senza. Assegnerò anche loro delle password.

postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE

Nota:le password fornite per i ruoli di fantasia sopra sono solo a scopo dimostrativo. Dovresti sempre sforzarti di fornire password univoche e rinforzate durante l'implementazione dei ruoli. Mentre una password è meglio di nessuna password, una password rafforzata è persino meglio di una banale.

Assegniamo a log_user gli attributi CREATEDB e CREATEROLE con il comando ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

È possibile verificare questi attributi impostati, controllando il catalogo pg_role. Due colonne di interesse sono rolcreaterole e rolcreatedb. Entrambi sono di tipo booleano, quindi dovrebbero essere impostati su t per true per questi attributi.

Conferma con una query SELECT simile.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper

Come si possono determinare i ruoli esistenti presenti nel database?

Due metodi disponibili sono il comando psql \du o la selezione dal catalogo pg_roles.

Qui sono entrambi in uso.

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)

Accesso

Diamo a entrambi i ruoli un'opportunità per accedere al server.

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

Per risolvere questo problema, dobbiamo scavare in quel file pg_hba.conf. La soluzione viene discussa mentre continuiamo in questo post, in quella sezione specifica.

Punti pratici

  • CREATE ROLE e la sua controparte, DROP ROLE, sono i tuoi comandi preferiti per implementare e rimuovere ruoli.
  • ALTER ROLE gestisce la modifica degli attributi di un ruolo.
  • I ruoli sono validi in tutti i database a causa della definizione a livello di cluster di database.
  • Tieni presente che la creazione di un nome di ruolo che inizia con un carattere speciale richiede di "affrontarlo" con virgolette doppie.
  • I ruoli e i relativi privilegi vengono stabiliti utilizzando gli attributi.
  • Per stabilire ruoli che richiedono l'attributo LOGIN per impostazione predefinita, CREATE USER è un comando opzionale a tua disposizione. Usati al posto di CREATE ROLE role_name LOGIN, sono essenzialmente uguali.

Il file pg_hba.conf - Stabilire un terreno comune tra il server e il client

Coprire tutti gli aspetti e le impostazioni per il file pg_hba.conf in un post del blog sarebbe nella migliore delle ipotesi scoraggiante. Invece, questa sezione presenterà le insidie ​​comuni che potresti incontrare e le soluzioni per porvi rimedio.

Le connessioni riuscite richiedono uno sforzo congiunto da entrambe le parti nel loro insieme. I ruoli che si connettono al server, devono comunque rispettare le restrizioni di accesso impostate a livello di database, dopo aver superato le impostazioni nel file pg_hba.conf.

Esempi rilevanti di questa relazione vengono inclusi man mano che questa sezione procede.

Per individuare il file pg_hba.conf, eseguire una query SELECT simile, in pg_settings VIEW. Devi essere loggato come SUPERUSER per interrogare questa VIEW.

postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

Il file pg_hba.conf contiene record che specificano uno dei sette formati disponibili per una determinata richiesta di connessione. Vedi lo spettro completo qui.

Ai fini di questo post del blog, esamineremo le impostazioni che puoi utilizzare per un ambiente locale.

Forse questo server è per il tuo continuo apprendimento e studio (come il mio).

Devo sottolineare in particolare che queste impostazioni non sono le impostazioni ottimali per un sistema rinforzato contenente più utenti.

I campi per questo tipo di connessione sono:

local database user auth-method [auth-options]

Dove significano:

locale - vengono tentate connessioni con socket di dominio Unix.

database:specifica i database denominati per questa corrispondenza di record.

utente:il nome utente del database corrispondente a questo record. Anche per questo campo è consentito un elenco separato da virgole di più utenti o tutti.

auth-method - Viene utilizzato quando una connessione corrisponde a questo record univoco. Le possibili scelte per questo campo sono:

  • fiducia
  • rifiuta
  • scram-sha-256
  • md5
  • password
  • gss
  • sspi
  • ident
  • pari
  • ldap
  • raggio
  • certificato
  • pam
  • bsd

Le righe impostate nel file pg_hba.conf per i ruoli nolog_user e log_user hanno il seguente aspetto:

local all nolog_user password
local all log_user password

Nota:poiché la password viene inviata in chiaro, non dovrebbe essere utilizzata in ambienti non attendibili con reti non attendibili.

Diamo un'occhiata a tre colonne interessanti da pg_hba_file_rules VIEW con la query seguente. Anche in questo caso il tuo ruolo ha bisogno dell'attributo SUPERUSER per interrogare questa VIEW.

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)

Possiamo vedere informazioni identiche dalle righe fornite sopra trovate nel file pg_hba.conf come possiamo dalla query di accompagnamento. A prima vista, sembra che entrambi i ruoli possano accedere.

Verificheremo e confermeremo.

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=>

Il punto chiave qui è che, sebbene nolog_user e log_user siano entrambi in grado di accedere in base al file pg_hba.conf, solo log_user può effettivamente accedere.

Laddove log_user ha superato le restrizioni di accesso a livello di database (avendo l'attributo LOGIN), nolog_user no.

Modifichiamo la riga log_user nel file pg_hba.conf e cambiamo il nome del database a cui questo ruolo può accedere. Ecco la modifica, che indica che log_user ora può accedere solo al database di prova.

local trial log_user password

Per prima cosa proviamo ad accedere al database postgres, a cui log_user aveva accesso in precedenza a causa del flag 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

Ora con il database di prova log_user ha il privilegio di

$ psql -U log_user -W trial
Password for user log_user: 
psql (10.1)
Type "help" for help.
trial=>

Nessun errore lì e il prompt trial=> mostra il database attualmente connesso.

Queste impostazioni si applicano anche all'ambiente del server, una volta stabilita una connessione.

Tentiamo di nuovo una connessione a quel database postgres:

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

Attraverso gli esempi presentati qui, dovresti essere a conoscenza delle opzioni di personalizzazione per i ruoli nel tuo cluster.

Nota:per rendere effettive le modifiche, spesso è necessario ricaricare il file pg_hba.conf.

Usa l'utilità pg_ctl per ricaricare il tuo server.

La sintassi sarebbe:

pg_ctl reload [-D datadir] [-s]

Per sapere dove si trova la tua datadir, puoi interrogare il sistema pg_settings VIEW, se effettuato l'accesso come SUPERUSER con una query SELECT simile come di seguito.

postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
           setting           
-----------------------------
 /var/lib/postgresql/10/main
(1 row)

Quindi, dai la tua shell all'utente postgres (o altro SUPERUSER) con:

$ sudo -u postgres bash

A meno che tu non abbia aggiunto l'utilità pg_ctl al tuo $PATH, devi qualificarla completamente per l'uso, quindi passare il comando da eseguire, insieme alla posizione di datadir.

Ecco un esempio:

$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled

Controlliamo lo stato del server con:

$ /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"

Punti pratici

  • I ruoli devono soddisfare i requisiti sia del file pg_hba.conf che dei privilegi di accesso a livello di database.
  • Il file pg_hba.conf viene controllato dall'alto verso il basso, per ogni richiesta di connessione. L'ordine nel file è significativo.

Privilegi e restrizioni per database, tabelle e colonne:ruoli personalizzati per attività e responsabilità

Affinché i ruoli possano utilizzare gli oggetti del database (tabelle, viste, colonne, funzioni, ecc...), devono essere loro concessi privilegi di accesso.

Il comando GRANT definisce questi privilegi essenziali.

Esamineremo alcuni esempi per ottenere l'essenza del suo utilizzo.

Creazione di database

Poiché a log_user sono stati concessi gli attributi CREATEDB e CREATEROLE, possiamo utilizzare questo ruolo per creare un database di test denominato trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Oltre a creare un nuovo RUOLO:

postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE

Infine, log_user si collegherà al nuovo database di prova:

postgres=> \c trial;
Password for user log_user: 
You are now connected to database "trial" as user "log_user".
trial=>

Notare che il prompt è cambiato nel nome 'trial' indicando che siamo collegati a quel database.

Utilizziamo log_user per CREARE una tabella simulata.

trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE

Il ruolo log_user ha recentemente creato un ruolo di supporto, db_user. Richiediamo che db_user disponga di privilegi limitati per la tabella another_workload.

Indubbiamente, la colonna sensitive_info non dovrebbe essere accessibile da questo ruolo. Anche i comandi INSERT, UPDATE e DELETE non dovrebbero essere concessi in questo momento, finché db_user non soddisfa determinate aspettative.

Tuttavia, db_user è necessario per emettere query SELECT. Come possiamo limitare le capacità di questi ruoli all'interno della tabella another_workload?

Per prima cosa esaminiamo l'esatta sintassi trovata nei documenti dei comandi di PostgreSQL GRANT, a livello di tabella.

GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]

Successivamente, implementiamo i requisiti stabiliti per il ruolo db_user, applicando una sintassi specifica.

trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT

Nota subito dopo la parola chiave SELECT, abbiamo elencato le colonne a cui db_user può accedere. Fino alla modifica, se db_user dovesse tentare query SELECT nella colonna sensitive_info o qualsiasi altro comando, tali query non verranno eseguite.

Con db_user connesso, lo metteremo in pratica, tentando una query SELECT per restituire tutte le colonne e i record dalla tabella.

trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload

La colonna sensitive_info è inclusa in questa query. Pertanto, nessun record viene restituito a db_user.

Ma db_user può SELEZIONARE le colonne consentite

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)

Funziona benissimo.

Verificheremo anche i comandi INSERT, UPDATE e 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

Non assegnando i comandi INSERT, UPDATE o DELETE a db_user, al ruolo viene negato l'accesso per utilizzarli.

Con la pletora di opzioni disponibili, la configurazione del tuo ruolo è praticamente illimitata. Puoi renderli completamente funzionali, in grado di eseguire qualsiasi comando o vincolati secondo le tue esigenze.

Punti pratici

  • Ai ruoli vengono forniti privilegi di accesso agli oggetti del database tramite il comando GRANT.
  • Gli oggetti e i comandi del database rispetto a tali oggetti sono altamente configurabili all'interno dell'ambiente PostgreSQL.

Chiusura

Grazie agli esempi forniti da questo post del blog, dovresti avere una migliore comprensione di:

  1. Creazione di un ruolo con attributi specifici.
  2. Impostazione di una connessione funzionante tra il client e il server, consentendo ai ruoli di accedere ai database.
  3. Personalizzazione elevata dei ruoli per soddisfare i requisiti individuali per l'accesso a livello di database, tabella e colonna implementando gli attributi necessari.