Introduzione
In un articolo precedente abbiamo introdotto le basi per comprendere gli schemi PostgreSQL, i meccanismi di creazione ed eliminazione e abbiamo esaminato diversi casi d'uso. Questo articolo approfondirà queste nozioni di base ed esplorerà la gestione dei privilegi relativi agli schemi.
Più sovraccarico terminologico
Ma c'è una questione preliminare che richiede chiarimenti. Ricordiamo che nel precedente articolo ci siamo soffermati su un possibile punto di confusione legato al sovraccarico del termine “schema”. Il significato specializzato di quel termine nel contesto dei database PostgreSQL è distinto da come viene generalmente utilizzato nei sistemi di gestione di database relazionali. Abbiamo un altro possibile kerfuffle terminologico simile per il presente argomento relativo alla parola "pubblico".
Al momento della creazione iniziale del database, il database Postgresql appena creato include uno schema predefinito denominato "pubblico". È uno schema come un altro, ma la stessa parola viene utilizzata anche come parola chiave che denota "tutti gli utenti" in contesti in cui altrimenti potrebbe essere utilizzato un nome di ruolo effettivo, come ad esempio ... attendi ... gestione dei privilegi dello schema . Il significato e i due usi distinti verranno chiariti negli esempi seguenti.
Interrogazione dei privilegi dello schema
Prima di renderlo concreto con il codice di esempio per concedere e revocare i privilegi dello schema, è necessario esaminare come esaminare i privilegi dello schema. Utilizzando l'interfaccia della riga di comando di psql, elenchiamo gli schemi e i privilegi associati con il comando \dn+. Per un database sampledb appena creato, vediamo questa voce per lo schema pubblico:
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =UC/postgres |
(1 row)
Le prime due e la quarta colonna sono piuttosto semplici:come accennato in precedenza, mostrano lo schema creato di default denominato "public", descritto come "schema pubblico standard" e di proprietà del ruolo "postgres". (La proprietà dello schema, se non diversamente specificato, è impostata sul ruolo che crea lo schema.) La terza colonna che elenca i privilegi di accesso è interessante qui. Il formato delle informazioni sul privilegio fornisce tre elementi:il beneficiario del privilegio, i privilegi e il concedente del privilegio nel formato "concessionario=privilegi/concedente" ovvero, a sinistra del segno di uguaglianza c'è il ruolo che riceve il privilegio(i), immediatamente a destra del segno di uguaglianza c'è un gruppo di lettere che specificano i privilegi particolari e, infine, dopo la barra il ruolo che ha concesso ai privilegi. Potrebbero esserci più specifiche di informazioni sui privilegi di questo tipo, elencate separate da un segno più poiché i privilegi sono additivi.
Per gli schemi sono possibili due privilegi che possono essere concessi separatamente:U per “USAGE” e C per “CREATE”. Il primo è necessario affinché un ruolo abbia la capacità di cercare oggetti di database come tabelle e viste contenute nello schema; quest'ultimo privilegio consente a un ruolo di creare oggetti di database nello schema. Esistono altre lettere per altri privilegi relativi a diversi tipi di oggetti di database, ma per gli schemi si applicano solo U e C.
Pertanto, per interpretare l'elenco dei privilegi sopra, la prima specifica ci dice che l'utente postgres ha ottenuto l'aggiornamento e crea i privilegi da solo sullo schema pubblico.
Si noti che per la seconda specifica sopra, a sinistra del segno di uguale appare una stringa vuota. In questo modo si indicano i privilegi concessi a tutti gli utenti, tramite la parola chiave PUBBLICA citata in precedenza.
Quest'ultima specifica di concedere l'utilizzo e creare privilegi sullo schema pubblico a tutti gli utenti è vista da alcuni come possibilmente contraria alle migliori pratiche dei principi di sicurezza generali, in cui si potrebbe preferire iniziare con l'accesso limitato per impostazione predefinita, richiedendo all'amministratore del database di concedere esplicitamente e privilegi di accesso minimi necessari. Questi privilegi liberali sullo schema pubblico sono appositamente configurati nel sistema per comodità e per compatibilità legacy.
Si noti inoltre che, fatta eccezione per le impostazioni dei privilegi permissivi, l'unica altra particolarità dello schema pubblico è che è elencato anche nel percorso_ricerca, come discusso nell'articolo precedente. Questo è simile per comodità:la configurazione search_path e i privilegi liberali insieme fanno sì che un nuovo database sia utilizzabile come se non esistesse un concetto come gli schemi.
Cenni storici sullo schema pubblico
Questo problema di compatibilità ha origine da circa quindici anni fa (prima di PostgreSQLversione 7.3, cfr. note di rilascio della versione 7.3) quando la funzionalità dello schema non faceva parte di PostgreSQL. La configurazione dello schema pubblico con privilegi liberali e la presenza del percorso_ricerca quando gli schemi sono stati introdotti nella versione 7.3 hanno consentito la compatibilità delle applicazioni precedenti, che non riconoscono lo schema, a funzionare senza modifiche con la funzionalità del database aggiornato.
Altrimenti non c'è nient'altro di particolarmente speciale nello schema pubblico:alcuni DBA lo eliminano se il loro caso d'uso non lo richiede; altri lo bloccano revocando i privilegi predefiniti.
Mostrami il codice - Revoca dei privilegi
Facciamo del codice per illustrare ed espandere ciò che abbiamo discusso finora.
I privilegi dello schema vengono gestiti con i comandi GRANT e REVOKE rispettivamente per aggiungere e ritirare i privilegi. Proveremo alcuni esempi specifici per bloccare lo schema pubblico, ma la sintassi generale è:
REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
FROM { [ GROUP ] role_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
Quindi, come esempio di blocco iniziale, rimuoviamo il privilegio di creazione dallo schema pubblico. Si noti che in questi esempi la parola minuscola "pubblico" si riferisce allo schema e potrebbe essere sostituita da qualsiasi altro nome di schema valido che potrebbe esistere nel database. La maiuscola "PUBLIC" è la parola chiave speciale che implica "tutti gli utenti" e potrebbe invece essere sostituita con un nome di ruolo specifico o un elenco di nomi di ruolo separati da virgole per un controllo dell'accesso più dettagliato.
sampledb=# REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =U/postgres |
(1 row)
L'unica differenza in questo elenco di privilegi dello schema rispetto al primo è l'assenza della "C" nella specifica del secondo privilegio, a verifica che il nostro comando fosse efficace:utenti diversi dall'utente postgres non possono più creare tabelle, viste o altri oggetti in lo schema pubblico.
Tieni presente che il comando precedente che revoca i privilegi di creazione dallo schema pubblico è la mitigazione consigliata per una vulnerabilità pubblicata di recente, CVE-2018-1058, che deriva dall'impostazione dei privilegi predefiniti nello schema pubblico.
Un ulteriore livello di blocco potrebbe comportare il negare completamente l'accesso di ricerca allo schema rimuovendo il privilegio di utilizzo:
sampledb=# REVOKE USAGE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres | standard public schema
(1 row)
Poiché tutti i privilegi dello schema disponibili per gli utenti non proprietari sono stati revocati, l'intera specifica del secondo privilegio scompare nell'elenco sopra.
Quello che abbiamo fatto con due comandi separati avrebbe potuto essere succintamente realizzato con un singolo comando specificando tutti i privilegi come:
sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
REVOKE
Inoltre, è anche possibile revocare i privilegi al proprietario dello schema:
sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM postgres;
REVOKE
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+-------------------+------------------------
public | postgres | | standard public schema
(1 row)
ma ciò in realtà non realizza nulla di pratico, poiché il proprietario dello schema conserva i privilegi completi sugli schemi di proprietà indipendentemente dall'assegnazione esplicita semplicemente in virtù della proprietà.
L'assegnazione del privilegio liberale per lo schema pubblico è un artefatto speciale associato alla creazione iniziale del database. Gli schemi creati successivamente in un database esistente sono conformi alla migliore pratica di avvio senza privilegi assegnati. Ad esempio, l'esame dei privilegi dello schema dopo la creazione di un nuovo schema denominato "privato" mostra che il nuovo schema non ha privilegi:
sampledb=# create schema private;
CREATE SCHEMA
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | |
public | postgres | | standard public schema
(2 rows)
Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper Mostrami il codice - Concessione dei privilegi
La forma generale del comando per aggiungere privilegi è:
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
where role_specification can be:
[ GROUP ] role_name
| PUBLIC
| CURRENT_USER
| SESSION_USER
Usando questo comando possiamo, ad esempio, consentire a tutti i ruoli di cercare oggetti di database nello schema privato aggiungendo il privilegio di utilizzo con
sampledb=# GRANT USAGE ON SCHEMA private TO PUBLIC;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres |
public | postgres | | standard public schema
(2 rows)
Nota come i privilegi UC appaiono per il proprietario di postgres come prima specifica, ora che abbiamo assegnato allo schema privilegi diversi da quelli predefiniti. La seconda specifica, =U/postgres, corrisponde al comando GRANT che abbiamo appena invocato come utente postgres che concede il privilegio di utilizzo a tutti gli utenti (dove, ricordiamo, la stringa vuota a sinistra del segno uguale implica "tutti gli utenti").
Un ruolo specifico, ad esempio denominato "utente1", può essere concesso sia per la creazione che per l'utilizzo dello schema privato con:
sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres +|
| | user1=UC/postgres |
public | postgres | | standard public schema
(2 rows)
Non abbiamo ancora menzionato la clausola "CON GRANT OPTION" del modulo di comando generale. Proprio come sembra, questa clausola consente a un ruolo concesso che il potere di concedere il privilegio specificato ad altri utenti ed è indicato nell'elenco dei privilegi da asterischi aggiunti al privilegio specifico:
sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1 WITH GRANT OPTION;
GRANT
sampledb=# \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+----------+----------------------+------------------------
private | postgres | postgres=UC/postgres+|
| | =U/postgres +|
| | user1=U*C*/postgres |
public | postgres | | standard public schema
(2 rows)
Conclusione
Questo conclude l'argomento di oggi. Come nota finale, tuttavia, ricorda che abbiamo discusso solo dei privilegi di accesso allo schema. Sebbene il privilegio USAGE consenta la ricerca di oggetti di database in uno schema, per accedere effettivamente agli oggetti per operazioni specifiche, come lettura, scrittura, esecuzione e così via, il ruolo deve anche disporre dei privilegi appropriati per tali operazioni su quegli oggetti di database specifici.