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

PostgreSQL-privilegier og brugerstyring - hvad du bør vide

Brugerstyring i PostgreSQL kan være vanskelig. Typisk administreres nye brugere i samråd inden for et par nøgleområder i miljøet. Ofte er privilegier perfekte på den ene front, men alligevel konfigureret forkert på den anden. Dette blogindlæg vil give praktiske 'Tips og Tricks' til en bruger eller rolle, som vi vil lære det at kende, opsætning i PostgreSQL.

De fagområder vi vil fokusere på er:

  • PostgreSQL's optagelse af roller

Du vil lære om roller, rolleegenskaber, bedste praksis for navngivning af dine roller og almindelige rolleopsætninger.

  • pg_hba.conf-filen

I dette afsnit vil vi se på en af ​​nøglefilerne og dens indstillinger for klient-side forbindelser og kommunikation med serveren.

  • Rettigheder og begrænsninger på database-, tabel- og kolonneniveau.

Ønsker du at konfigurere roller til optimal ydeevne og brug? Indeholder dine tabeller følsomme data, kun tilgængelige for privilegerede roller? Men med behovet for at tillade forskellige roller at udføre begrænset arbejde? Disse spørgsmål og flere vil blive afsløret i dette afsnit.

PostgreSQL's påtagelse af roller - Hvad er en "rolle", og hvordan opretter man en?

Tilladelser til databaseadgang i PostgreSQL håndteres med konceptet om en rolle, som er beslægtet med en bruger. Roller kan også repræsentere grupper af brugere i PostgreSQL-økosystemet.

PostgreSQL etablerer kapaciteten for roller til at tildele privilegier til databaseobjekter, de ejer, hvilket muliggør adgang og handlinger til disse objekter. Roller har mulighed for at give medlemskab til en anden rolle. Attributter giver tilpasningsmuligheder for tilladt klientgodkendelse.

Attributter for roller gennem CREATE ROLE-kommandoen er tilgængelige i den officielle PostgreSQL-dokumentation.

Nedenfor er de attributter, du normalt vil tildele, når du opretter en ny rolle. De fleste af disse er selvforklarende. Der gives dog en kort beskrivelse for at fjerne enhver forvirring sammen med eksempler på anvendelser.

SUPERBRUGER - En database SUPERBRUGER fortjener en advarsel. Nederst kan roller med denne attribut oprette endnu en SUPERBRUGER. Faktisk er denne attribut påkrævet for at oprette en anden SUPERUSER-rolle. Da roller med denne egenskab omgår alle tilladelsestjek, skal du give dette privilegium fornuftigt.

CREATEDB - Tillader rollen at oprette databaser.

CREATEROLE - Med denne attribut kan en rolle udstede kommandoen CREATE ROLE. Opret derfor andre roller.

LOGIN - Aktiverer muligheden for at logge ind. Et rollenavn med denne attribut kan bruges i klientforbindelseskommandoen. Flere detaljer om denne egenskab med kommende eksempler.

Visse attributter har en eksplicit modsat navngivet kommando og er typisk standard, når de efterlades uspecificeret.

f.eks.
SUPERBRUGER | NOSUPERUSER
CREATEROLE |NOCREATEROLE
LOG PÅ |NOLOGIN

Lad os se på nogle af disse attributter i aktion for forskellige konfigurationer, du kan konfigurere for at komme i gang.

Oprettelse og slip af roller

At skabe en rolle er relativt ligetil. Her er et hurtigt eksempel:

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

Hvad gik galt der? Det viser sig, at rollenavne ikke kan begynde med andet end et bogstav.

"Hvad med at pakke navnet ind i dobbelte anførselstegn?" Lad os se:

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

Det virkede, selvom det nok ikke var en god idé. Hvad med et specialtegn i midten af ​​navnet?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Intet problem der. Selv uden dobbelte anførselstegn blev der ikke returneret nogen fejl.

Jeg er bare ikke vild med navnestrukturen for $money_man for en bruger. Jeg dropper dig $money_man og starter forfra. Kommandoen DROP ROLE sørger for at fjerne en rolle. Her er den i brug.

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

Og endnu en fejl med rollen $money_man. Igen, ty til de dobbelte anførselstegn det er.

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

LOGIN-privilegiet

Lad os se på to forskellige brugere, en med LOGIN-privilegiet og en uden. Jeg vil også tildele dem adgangskoder.

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

Bemærk:Adgangskoderne til ovenstående fiktive roller er kun til demonstrationsformål. Du bør altid stræbe efter at give unikke og hærdede adgangskoder, når du implementerer roller. Selvom en adgangskode er bedre end ingen adgangskode, er en hærdet adgangskode endnu bedre end en triviel.

Lad os tildele log_user attributterne CREATEDB og CREATEROLE med kommandoen ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Du kan verificere disse sæt attributter ved at tjekke pg_role kataloget. To kolonner af interesse er rolcreaterole og rolcreatedb. Begge er af den boolske datatype, så de skal sættes til t for sand for disse attributter.

Bekræft med en lignende SELECT-forespørgsel.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Download Whitepaper Today PostgreSQL Management &Automation med ClusterControlFå flere oplysninger om, hvad du skal vide for at implementere, overvåge, administrere og skalere PostgreSQLDownload Whitepaper

Hvordan kan du bestemme de eksisterende roller i databasen?

To tilgængelige metoder er kommandoen psql \du eller at vælge fra pg_roles-kataloget.

Her er de begge i brug.

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)

Logger ind

Lad os give begge roller en mulighed for at logge ind på serveren.

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

For at løse dette problem skal vi grave i den pg_hba.conf fil. Løsningen diskuteres, mens vi fortsætter i dette indlæg, til det specifikke afsnit.

Handtagbare takeaways

  • CREATE ROLE og dens modstykke, DROP ROLE, er dine go-to-kommandoer til implementering og fjernelse af roller.
  • ALTER ROLE håndterer ændring af attributterne for en rolle.
  • Roller er gyldige i alle databaser på grund af definition på databaseklyngeniveau.
  • Husk, at oprettelse af et rollenavn, der begynder med et specialtegn, kræver, at du 'adresserer' det med dobbelte anførselstegn.
  • Roller og deres privilegier etableres ved hjælp af attributter.
  • For at etablere roller, der har brug for LOGIN-attributten som standard, er CREATE USER en valgfri kommando til din rådighed. Brugt i stedet for CREATE ROLE role_name LOGIN, er de stort set ens.

pg_hba.conf-filen - Etablering af fælles grundlag mellem serveren og klienten

At dække alle aspekter og indstillinger for filen pg_hba.conf i ét blogindlæg ville i bedste fald være skræmmende. I stedet vil dette afsnit præsentere almindelige faldgruber, du kan støde på, og løsninger til at afhjælpe dem.

Succesfulde forbindelser kræver en konjunktiv indsats fra begge dele som helhed. Roller, der forbinder til serveren, skal stadig opfylde adgangsbegrænsninger, der er indstillet på databaseniveau, efter at have overført indstillingerne i filen pg_hba.conf.

Relevante eksempler på dette forhold er inkluderet, efterhånden som dette afsnit skrider frem.

For at finde din pg_hba.conf fil, udsend en lignende SELECT-forespørgsel i pg_settings VIEW. Du skal være logget ind som SUPERBRUGER for at forespørge på denne 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)

Filen pg_hba.conf indeholder poster, der specificerer et af syv tilgængelige formater for en given forbindelsesanmodning. Se hele spektret her .

I forbindelse med dette blogindlæg vil vi se på indstillinger, du kan bruge til et lokalt miljø.

Måske er denne server til din fortsatte læring og studier (som min er).

Jeg skal især bemærke, at disse indstillinger ikke er de optimale indstillinger for et hærdet system, der indeholder flere brugere.

Felterne for denne type forbindelse er:

local database user auth-method [auth-options]

Hvor de betyder:

lokal - forbindelser forsøges med Unix-domæne-sockets.

database - Angiver databasen/databaserne, der er navngivet for denne postmatch.

bruger - Databasens brugernavn, der matcher denne post. En kommasepareret liste over flere brugere eller alle er også tilladt for dette felt.

auth-method - bruges, når en forbindelse matcher denne unikke post. De mulige valg for dette felt er:

  • tillid
  • afvis
  • scram-sha-256
  • md5
  • adgangskode
  • gss
  • sspi
  • ident
  • peer
  • ldap
  • radius
  • certifikat
  • pam
  • bsd

Linjerne sat i filen pg_hba.conf for rollerne nolog_user og log_user ser sådan ud:

local all nolog_user password
local all log_user password

Bemærk:Da adgangskoden sendes i klartekst, bør dette ikke bruges i upålidelige miljøer med ikke-pålidelige netværk.

Lad os se på tre interessante kolonner fra pg_hba_file_rules VIEW med nedenstående forespørgsel. Igen skal din rolle have SUPERUSER-attributten for at forespørge på denne 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)

Vi kan se identiske oplysninger fra linjerne ovenfor, som findes i filen pg_hba.conf, som vi kan fra den medfølgende forespørgsel. Ved første øjekast ser det ud til, at begge roller kan logge ind.

Vi vil teste og bekræfte.

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

Det vigtigste her er, at selvom nolog_user og log_user begge er i stand til at logge ind i henhold til filen pg_hba.conf, er det kun log_user, der rent faktisk har lov til at logge ind.

Hvor log_user bestod adgangsbegrænsningerne på databaseniveau (ved at have LOGIN-attributten), gjorde nolog_user det ikke.

Lad os redigere log_users linje i filen pg_hba.conf og ændre databasenavnet, som denne rolle har adgang til. Her er ændringen, hvilket indikerer, at log_user nu kun kan logge ind på prøvedatabasen.

local trial log_user password

Lad os først prøve at logge ind på postgres-databasen, som log_user tidligere havde adgang til på grund af all-flaget.

$ 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

Nu med prøvedatabasen har log_user privilegium til

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

Ingen fejl der, og trial=>-prompten viser den aktuelt tilsluttede database.

Disse indstillinger gælder også i servermiljøet, når en forbindelse er etableret.

Lad os prøve at oprette forbindelse til den postgres-database igen:

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

Gennem de eksempler, der præsenteres her, bør du være opmærksom på tilpasningsmulighederne for rollerne i din klynge.

Bemærk:Ofte er det nødvendigt at genindlæse filen pg_hba.conf for at ændringerne kan træde i kraft.

Brug pg_ctl-værktøjet til at genindlæse din server.

Syntaksen ville være:

pg_ctl reload [-D datadir] [-s]

For at vide, hvor din datadir er, kan du forespørge pg_settings-systemet VIEW, hvis du er logget ind som SUPERUSER med en lignende SELECT-forespørgsel som nedenfor.

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

Giv derefter din shell til postgres-brugeren (eller anden SUPERUSER) med:

$ sudo -u postgres bash

Medmindre du har tilføjet pg_ctl-værktøjet til din $PATH, skal du fuldt ud kvalificere det til brug og derefter sende kommandoen til at udføre sammen med datadir-placeringen.

Her er et eksempel:

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

Lad os tjekke serverens status med:

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

Handtagbare takeaways

  • Roller skal opfylde kravene fra både pg_hba.conf-filen og adgangsrettigheder på databaseniveau.
  • pg_hba.conf-filen kontrolleres fra toppen og ned for hver forbindelsesanmodning. Rækkefølgen i filen er væsentlig.

Database-, tabel- og kolonneprivilegier og begrænsninger - Skræddersyede roller til opgaver og ansvar

For at roller kan bruge databaseobjekter (tabeller, visninger, kolonner, funktioner osv...), skal de have adgangsrettigheder til dem.

GRANT-kommandoen definerer disse væsentlige privilegier.

Vi vil gennemgå et par eksempler for at få essensen af ​​dets brug.

Oprettelse af databaser

Da log_user blev tildelt attributterne CREATEDB og CREATEROLE, kan vi bruge denne rolle til at oprette en testdatabase med navnet trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Ud over at oprette en ny ROLLE:

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

Til sidst vil log_user oprette forbindelse til den nye prøvedatabase:

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

Bemærk, at prompten blev ændret til navnet "prøveversion", hvilket indikerer, at vi er forbundet til den database.

Lad os bruge log_user til at SKABE en mock tabel.

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

Rolle log_user har for nylig oprettet en hjælperrolle, db_user. Vi kræver, at db_user har begrænsede privilegier til tabellen another_workload.

Uden tvivl bør kolonnen sensitive_info ikke tilgås af denne rolle. INSERT, UPDATE og DELETE kommandoer bør heller ikke gives på nuværende tidspunkt, før db_user opfylder visse forventninger.

Dog skal db_user udsende SELECT-forespørgsler. Hvordan kan vi begrænse denne rolles evner i tabellen another_workload?

Lad os først undersøge den nøjagtige syntaks, der findes i PostgreSQL GRANT-kommandodokumenterne på tabelniveau.

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

Dernæst implementerer vi kravene til rolle db_user ved at anvende specifik syntaks.

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

Bemærk lige efter SELECT nøgleordet, vi listede de kolonner, som db_user kan få adgang til. Hvis db_user forsøger at vælge forespørgsler i kolonnen sensitive_info eller en anden kommando for den sags skyld, vil disse forespørgsler ikke blive udført, indtil de ændres.

Med db_user logget ind, vil vi omsætte dette i praksis ved at forsøge en SELECT-forespørgsel for at returnere alle kolonner og poster fra tabellen.

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

Column sensitive_info er inkluderet i denne forespørgsel. Derfor returneres ingen poster til db_user.

Men db_user kan VÆLGE de tilladte kolonner

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)

Det fungerer fint.

Vi tester også kommandoerne INSERT, UPDATE og 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

Ved ikke at tildele kommandoer INSERT, UPDATE eller DELETE til db_user, nægtes rollen adgang til at bruge dem.

Med overfloden af ​​tilgængelige muligheder er konfigurationen af ​​din rolle praktisk talt ubegrænset. Du kan gøre dem fuldt funktionelle, i stand til at udføre enhver kommando eller så begrænsede, som dine krav tilsiger.

Handtagbare takeaways

  • Roller gives adgangsrettigheder til databaseobjekter via GRANT-kommandoen.
  • Databaseobjekter og kommandoer mod disse objekter er meget konfigurerbare i PostgreSQL-miljøet.

Lukker

Gennem dette blogindlægs anførte eksempler bør du have en bedre forståelse af:

  1. Oprettelse af en rolle med specifikke attributter.
  2. Indstilling af en brugbar forbindelse mellem klienten og serveren, hvilket giver roller login-adgang til databaser.
  3. Stærkt tilpasning af dine roller til at opfylde individuelle krav til database-, tabel- og kolonneniveauadgang ved at implementere nødvendige attributter.

  1. Sådan bruger du flere databaser dynamisk til en model i CakePHP

  2. Erklæring af tupelstrukturen af ​​en post i PL/pgSQL

  3. docker postgres med indledende data er ikke persisted over commits

  4. SQL-forespørgsel til at oprette database i MySQL