Come gestire PRIVILEGI PREDEFINITI per gli UTENTI su un DATABASE vs SCHEMA?


48

Voglio migrare un'applicazione abbastanza semplice, interna, basata su database da SQLite3 a PostgreSQL 9.3 e rafforzare le autorizzazioni nel DB mentre procedo.

L'applicazione attualmente consiste in un comando per aggiornare i dati; e uno per interrogarlo. Naturalmente, dovrò anche mantenere il database in altri modi (creare nuove tabelle, viste, trigger, ecc.).

Mentre questa applicazione sarà l'unica ospitata inizialmente sul server, preferirei supporre che in futuro potrebbe essere ospitata su un server con altri database, piuttosto che dover rimescolare più tardi se ciò diventa necessario in il futuro.

Penserei che questi sarebbero un insieme abbastanza comune di requisiti, ma ho difficoltà a trovare un semplice tutorial che spiega come impostare un nuovo database in PostgreSQL, con questo tipo di separazione utente / privilegio. I riferimenti continuano a lungo su gruppi, utenti, ruoli, database, schemi e dominio; ma li trovo confusi.

Ecco cosa ho provato finora (dall'interno psqlcome 'postgres'):

CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;
\connect hostdb
CREATE SCHEMA hostdb;
CREATE USER hostdb_admin WITH PASSWORD 'youwish';
CREATE USER hostdb_mgr   WITH PASSWORD 'youwish2';
CREATE USER hostdb_usr WITH PASSWORD 'youwish3';

GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin;
GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT ON TABLES TO hostdb_usr;

Ma non sto ottenendo la semantica prevista. Voglio averlo configurato in modo che solo gli utenti hostdb_adminpossano creare (e rilasciare e modificare) le tabelle; la hostdb_mgrpuò leggere, inserire, aggiornare e cancellare su tutti i tavoli per impostazione predefinita; e hostdb_usrpuò solo leggere tutte le tabelle (e le viste).

Quando ho provato questo ho scoperto che ero in grado di creare tabelle hostdbcome uno di questi utenti; ma, per ogni utente, potrei solo leggere o modificare le tabelle create da quell'utente, a meno che non utilizzi un esplicito GRANT.

Immagino che manchi qualcosa tra CREATE DATABASEe CREATE SCHEMA, qualcosa da applicare SCHEMAal DATABASE?

(Man mano che le cose diventano più avanzate, avrò anche delle domande per applicare restrizioni simili su TRIGGERS, stored procedure VIEWSe forse altri oggetti).

Dove posso trovare una guida decente, tutorial o serie di video su questo?


2
Penso che (almeno una parte di) il tuo problema risieda nella publicpseudorole. Può essere pensato come un ruolo di cui fa parte ogni altro ruolo (utente, gruppo, tutti uguali). Prova a rimuovere i privilegi da esso, ad esempio REVOKE CREATE ON SCHEMA hostdb FROM public,. La revoca dei diritti a livello di database, come hai fatto, disabilita solo alcune autorizzazioni a livello di database, nessun effetto su schemi o tabelle.
dezso,

@dezso: potrebbe esserci un malinteso riguardo ai privilegi di default per gli schemi. Solo lo schema predefinito publicaccade con i privilegi per PUBLIC. Oltre a questo, ci sono non i privilegi di default per nuovi schemi. Quindi questo non influisce sul caso d'uso dimostrato. Vedi il capitolo nella mia risposta.
Erwin Brandstetter,

Risposte:


86

Dove posso trovare una guida decente, tutorial o serie di video su questo?

Troverai tutto nel manuale. Link sotto.
Certo, la questione non è banale e talvolta confusa. Ecco una ricetta per il caso d'uso:

Ricetta

Voglio averlo configurato in modo che solo gli utenti hostdb_adminpossano creare (e rilasciare e modificare) le tabelle;
la hostdb_mgrpuò leggere, inserire, aggiornare e cancellare su tutti i tavoli per impostazione predefinita;
e hostdb_usrpuò solo leggere tutte le tabelle (e le viste).

Come superutente postgres:

CREATE USER schma_admin WITH PASSWORD 'youwish';
-- CREATE USER schma_admin WITH PASSWORD 'youwish' CREATEDB CREATEROLE; -- see below
CREATE USER schma_mgr   WITH PASSWORD 'youwish2';
CREATE USER schma_usr   WITH PASSWORD 'youwish3';

Se desideri un amministratore più potente in grado di gestire anche database e ruoli, aggiungi gli attributiCREATEDBCREATEROLE del ruolo e sopra.

Concedi ogni ruolo al livello superiore successivo, quindi tutti i livelli "ereditano" almeno l'insieme di privilegi dal livello inferiore successivo (a cascata):

GRANT schma_usr TO schma_mgr;
GRANT schma_mgr TO schma_admin;

CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;  -- see notes below!

GRANT CONNECT ON DATABASE hostdb TO schma_usr;  -- others inherit

\connect hostdb  -- psql syntax

Sto nominando lo schema schma(non hostdbche sarebbe confuso). Scegli qualsiasi nome. Facoltativamente, rendere schma_adminil proprietario dello schema:

CREATE SCHEMA schma AUTHORIZATION schma_admin;

SET search_path = schma;  -- see notes

ALTER ROLE schma_admin IN DATABASE hostdb SET search_path = schma; -- not inherited
ALTER ROLE schma_mgr   IN DATABASE hostdb SET search_path = schma;
ALTER ROLE schma_usr   IN DATABASE hostdb SET search_path = schma;

GRANT USAGE  ON SCHEMA schma TO schma_usr;
GRANT CREATE ON SCHEMA schma TO schma_admin;

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT SELECT                           ON TABLES TO schma_usr;  -- only read

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO schma_mgr;  -- + write, TRUNCATE optional

ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO schma_mgr;  -- SELECT, UPDATE are optional 

Per le and drop and alternote di seguito.

Man mano che le cose diventano più avanzate, avrò anche delle domande per applicare restrizioni simili su TRIGGERS, procedure memorizzate VIEWSe forse altri oggetti.

Le viste sono speciali. Per uno:

... (ma si noti che ALL TABLESè considerato includere viste e tabelle esterne).

E per le viste aggiornabili :

Si noti che l'utente che esegue l'inserimento, l'aggiornamento o l'eliminazione nella vista deve disporre del corrispondente privilegio di inserimento, aggiornamento o eliminazione nella vista. Inoltre, il proprietario della vista deve disporre dei privilegi pertinenti sulle relazioni di base sottostanti, ma l'utente che esegue l'aggiornamento non necessita di autorizzazioni per le relazioni di base sottostanti (vedere la Sezione 38.5 ).

Anche i trigger sono speciali. È necessario il TRIGGERprivilegio sul tavolo e:

Ma stiamo già espandendo eccessivamente l'ambito di questa domanda ...

Note importanti

Proprietà

Se si desidera consentire schma_admin(solo) l'eliminazione e la modifica delle tabelle, rendere il ruolo proprietario di tutti gli oggetti. La documentazione:

Il diritto di rilasciare un oggetto o di modificarne la definizione in alcun modo, non è trattato come un privilegio concedibile; è inerente al proprietario e non può essere concesso o revocato. (Tuttavia, un effetto simile può essere ottenuto concedendo o revocando l'appartenenza al ruolo che possiede l'oggetto; vedere di seguito.) Il proprietario ha implicitamente tutte le opzioni di concessione anche per l'oggetto.

ALTER TABLE some_tbl OWNER TO schma_admin;

Oppure crea tutti gli oggetti con il ruoloschma_adminper cominciare, quindi non è necessario impostare esplicitamente il proprietario. Semplifica anche i privilegi di default, che devi solo impostare per un ruolo:

Oggetti preesistenti

I privilegi predefiniti si applicano solo agli oggetti appena creati e solo per il ruolo particolare con cui vengono creati. Ti consigliamo di adattare anche le autorizzazioni per gli oggetti esistenti :

Lo stesso vale se si creano oggetti con un ruolo che non è stato DEFAULT PRIVILEGESimpostato, come il superutente postgres. Riassegna la proprietà schma_admine imposta i privilegi manualmente - o imposta anche DEFAULT PRIVILEGESper postgres(mentre sei connesso al DB giusto!):

ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ...  -- etc.

Privilegi predefiniti

Ti mancava un aspetto importante del ALTER DEFAULT PRIVILEGEScomando. Si applica al ruolo attuale se non diversamente specificato:

I privilegi predefiniti si applicano solo al database corrente. Quindi non si scherza con altri database nel cluster DB. La documentazione:

per tutti gli oggetti creati nel database corrente

Si potrebbe anche voler impostare i privilegi di default per FUNCTIONSe TYPES(non solo TABLESe SEQUENCES), ma quelli che non potrebbe essere necessario.

Privilegi predefiniti per PUBLIC

I privilegi di default concessi PUBLICsono rudimentali e sopravvalutati da alcuni. La documentazione:

PostgreSQL concede i privilegi di default su alcuni tipi di oggetti a PUBLIC. Nessun privilegio è concesso per PUBLICimpostazione predefinita su tabelle, colonne, schemi o tablespace. Per altri tipi, i privilegi predefiniti concessi PUBLICsono i seguenti: CONNECTe CREATE TEMP TABLEper i database; EXECUTEprivilegio per le funzioni; e USAGE privilegio per le lingue.

Enorme enfasi sulla mia. in genere l'unico comando sopra è sufficiente per coprire tutto:

REVOKE ALL ON DATABASE hostdb FROM public;

In particolare, non sono concessi privilegi predefiniti PUBLICper i nuovi schemi. Potrebbe essere confuso che lo schema predefinito denominato "pubblico" inizi con i ALLprivilegi per PUBLIC. Questa è solo una funzione di praticità per facilitare l'inizio con i database appena creati. Non influisce in alcun modo su altri schemi. È possibile revocare questi privilegi nel database dei modelli template1, quindi tutti i database appena creati in questo cluster iniziano senza di essi:

\connect template1
REVOKE ALL ON SCHEMA public FROM public;

Il privilegio TEMP

Poiché abbiamo revocato tutti i privilegi hostdbda PUBLIC, gli utenti regolari non possono creare tabelle temporanee a meno che non lo consentiamo esplicitamente. È possibile o meno aggiungere questo:

GRANT TEMP ON DATABASE hostdb TO schma_mgr;

search_path

Non dimenticare di impostare il search_path. Se hai solo un database nel cluster, puoi semplicemente impostare il default globale in postgresql.conf. Altrimenti (più probabilmente) impostalo come proprietà del database o solo per i ruoli coinvolti o anche la combinazione di entrambi. Dettagli:

Puoi impostarlo su schma, publicse usi anche lo schema pubblico o anche (meno probabilmente) $user, schma, public...

Un'alternativa sarebbe quella di utilizzare lo schema predefinito "pubblico" che dovrebbe funzionare con le impostazioni predefinite a search_pathmeno che non sia stato modificato. Ricorda di revocare i privilegi per PUBLICin questo caso.

Relazionato


Stavo cercando come aggiungere privilegi di amministratore predefiniti al superutente appena creato, quindi non avrei avuto bisogno di dargli addizionale emotivo su ogni tavolo. E l'ho trovato. E thissembra un'istruzione per l'astronave ...
Denis Matafonov,

@DenisMatafonov: i superutenti hanno automaticamente tutti i privilegi. Ti suggerisco di iniziare una nuova domanda con i dettagli del tuo caso. I commenti non sono il posto giusto. Puoi sempre collegarti a domande / risposte correlate per il contesto.
Erwin Brandstetter,

Sì, i super utenti hanno tutti gli accessi, ma non puoi generalizzare i loro privilegi di default. Sarebbe davvero bello impostare i privilegi di default per un ruolo in uno schema e far applicare quei valori predefiniti a tutti i membri del ruolo mentre creano le tabelle nello schema. Ad esempio, per dire "assicurarsi che tutte le tabelle create in questo schema da chiunque nel team di progettazione siano leggibili da chiunque nel team di reporting". In breve, voglio che i membri di un ruolo di creazione di tabelle ereditino i privilegi predefiniti.
combinatore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.