sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL-privilegier och användarhantering - vad du bör veta

Användarhantering inom PostgreSQL kan vara knepigt. Vanligtvis hanteras nya användare, tillsammans, inom ett par nyckelområden i miljön. Ofta är privilegier perfekta på en front, men konfigurerade felaktigt på den andra. Det här blogginlägget kommer att ge praktiska "Tips och tricks" för en användare eller roll, som vi kommer att lära känna den, inställning inom PostgreSQL.

Ämnesområdena vi kommer att fokusera på är:

  • PostgreSQL:s roller

Du kommer att lära dig om roller, rollattribut, bästa praxis för att namnge dina roller och vanliga rollinställningar.

  • Pg_hba.conf-filen

I det här avsnittet kommer vi att titta på en av nyckelfilerna och dess inställningar, för anslutningar på klientsidan och kommunikation med servern.

  • Behörigheter och begränsningar på databas-, tabell- och kolumnnivå.

Vill du konfigurera roller för optimal prestanda och användning? Innehåller dina tabeller känsliga uppgifter, endast tillgängliga för privilegierade roller? Men med behovet av att tillåta olika roller att utföra ett begränsat arbete? Dessa frågor och fler kommer att exponeras i det här avsnittet.

PostgreSQL tar på sig roller - Vad är en "roll" och hur skapar man en?

Behörigheter för databasåtkomst inom PostgreSQL hanteras med konceptet en roll, som är besläktad med en användare. Roller kan också representera grupper av användare i PostgreSQL-ekosystemet.

PostgreSQL etablerar kapaciteten för roller att tilldela privilegier till databasobjekt de äger, vilket möjliggör åtkomst och åtgärder för dessa objekt. Roller har möjlighet att ge medlemskap till en annan roll. Attribut ger anpassningsalternativ för tillåten klientautentisering.

Attribut för roller genom kommandot CREATE ROLE, är tillgängliga i den officiella PostgreSQL-dokumentationen.

Nedan finns de attribut som du vanligtvis tilldelar när du skapar en ny roll. De flesta av dessa är självförklarande. En kort beskrivning tillhandahålls dock för att reda ut eventuell förvirring tillsammans med exempel på användningar.

SUPERANVÄNDARE - En databas SUPERANVÄNDARE förtjänar ett varningens ord. Sammanfattningsvis kan roller med detta attribut skapa ytterligare en SUPERANVÄNDARE. Faktum är att detta attribut krävs för att skapa en annan SUPERANVÄNDARE-roll. Eftersom roller med det här attributet går förbi alla behörighetskontroller, bevilja denna behörighet med omtanke.

CREATEDB - Tillåter rollen att skapa databaser.

CREATEROLE - Med detta attribut kan en roll utfärda kommandot CREATE ROLE. Skapa därför andra roller.

LOGGA IN - Aktiverar möjligheten att logga in. Ett rollnamn med detta attribut kan användas i klientanslutningskommandot. Mer information om detta attribut med kommande exempel.

Vissa attribut har ett uttryckligt motsatt namnkommando och är vanligtvis standard när de lämnas ospecificerade.

t.ex.
SUPERANVÄNDARE | NOSUPERUSER
CREATEROLE |NOCREATEROLE
LOGGA IN |NOLOGIN

Låt oss titta på några av dessa attribut i praktiken för olika konfigurationer som du kan ställa in för att komma igång.

Skapa och släppa roller

Att skapa en roll är relativt enkelt. Här är ett snabbt exempel:

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

Vad gick fel där? Det visar sig att rollnamn inte kan börja med något annat än en bokstav.

"Vad sägs om att slå in namnet med dubbla citattecken?" Låt oss se:

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

Det fungerade, även om det förmodligen inte var en bra idé. Vad sägs om ett specialtecken i mitten av namnet?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Inga problem där. Även utan dubbla citattecken returnerades inget fel.

Jag är helt enkelt inte förtjust i namnstrukturen för $money_man för en användare. Jag släpper dig $money_man och börjar om på nytt. Kommandot DROP ROLE tar bort en roll. Här är den i bruk.

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

Och ett annat fel med rollen $money_man. Återigen, med dubbla citattecken.

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

LOGGA IN-privilegiet

Låt oss titta på två olika användare, en med LOGIN-privilegiet och en utan. Jag kommer att tilldela dem lösenord också.

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

Obs:Lösenorden som tillhandahålls till ovanstående fiktiva roller är endast för demonstrationsändamål. Du bör alltid sträva efter att tillhandahålla unika och härdade lösenord när du implementerar roller. Även om ett lösenord är bättre än inget lösenord, är ett härdat lösenord till och med bättre än ett trivialt.

Låt oss tilldela log_user attributen CREATEDB och CREATEROLE med kommandot ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Du kan verifiera dessa uppsättningsattribut genom att kontrollera pg_role-katalogen. Två kolumner av intresse är rolcreaterole och rolcreatedb. Båda är av den booleska datatypen så de bör sättas till t för sant för dessa attribut.

Bekräfta med en liknande SELECT-fråga.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Ladda ner Whitepaper Today PostgreSQL Management &Automation med ClusterControlLäs om vad du behöver veta för att distribuera, övervaka, hantera och skala PostgreSQLDladda Whitepaper

Hur kan du avgöra vilka roller som finns i databasen?

Två tillgängliga metoder är kommandot psql \du eller att välja från pg_roles-katalogen.

Här är de båda i bruk.

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)

Loggar in

Låt oss ge båda rollerna en möjlighet att logga in på servern.

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

För att lösa det här problemet måste vi gräva i filen pg_hba.conf. Lösningen diskuteras när vi fortsätter i det här inlägget, till det specifika avsnittet.

Aktiveringsbara takeaways

  • CREATE ROLE och dess motsvarighet, DROP ROLE, är dina go-to-kommandon för att implementera och ta bort roller.
  • ALTER ROLE hanterar att ändra attributen för en roll.
  • Roller är giltiga inom alla databaser på grund av definition på databasklusternivå.
  • Kom ihåg att skapa ett rollnamn som börjar med ett specialtecken kräver att du "adresserar" det med dubbla citattecken.
  • Roller och deras privilegier upprättas med hjälp av attribut.
  • För att skapa roller som behöver LOGIN-attributet som standard, är CREATE USER ett valfritt kommando till ditt förfogande. Används i stället för CREATE ROLE role_name LOGIN, de är i princip lika.

pg_hba.conf-filen - Etablering av gemensam grund mellan servern och klienten

Att täcka alla aspekter och inställningar för filen pg_hba.conf i ett blogginlägg skulle i bästa fall vara skrämmande. Istället kommer detta avsnitt att presentera vanliga fallgropar du kan stöta på och lösningar för att åtgärda dem.

Framgångsrika anslutningar kräver en konjunktiv ansträngning från båda delarna som helhet. Roller som ansluter till servern måste fortfarande uppfylla åtkomstbegränsningar som ställts in på databasnivå efter att ha skickat inställningarna i filen pg_hba.conf.

Relevanta exempel på detta förhållande inkluderas allt eftersom det här avsnittet fortskrider.

För att hitta din pg_hba.conf-fil, skicka en liknande SELECT-fråga i vyn pg_settings. Du måste vara inloggad som SUPERANVÄNDARE för att fråga denna 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 innehåller poster som anger ett av sju tillgängliga format för en given anslutningsförfrågan. Se hela spektrat här .

I detta blogginlägg kommer vi att titta på inställningar du kan använda för en lokal miljö.

Kanske är den här servern till för att du ska fortsätta lära dig och studera (som min är).

Jag måste särskilt notera att dessa inställningar inte är de optimala inställningarna för ett härdat system som innehåller flera användare.

Fälten för denna typ av anslutning är:

local database user auth-method [auth-options]

Där de betyder:

lokal - anslutningar görs med Unix-domänsockets.

databas - Anger databasen/databaserna som namnges för denna postmatchning.

användare – Databasanvändarnamnet som matchade denna post. En kommaseparerad lista med flera användare eller alla är också tillåten för detta fält.

auth-method - Används när en anslutning matchar denna unika post. De möjliga valen för detta fält är:

  • lita
  • avvisa
  • scram-sha-256
  • md5
  • lösenord
  • gss
  • sspi
  • ident
  • peer
  • ldap
  • radie
  • certifikat
  • pam
  • bsd

Raderna i filen pg_hba.conf för rollerna nolog_user och log_user ser ut så här:

local all nolog_user password
local all log_user password

Obs! Eftersom lösenord skickas i klartext bör detta inte användas i opålitliga miljöer med opålitliga nätverk.

Låt oss titta på tre intressanta kolumner från pg_hba_file_rules VIEW med frågan nedan. Återigen behöver din roll SUPERUSER-attributet för att fråga denna 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 identisk information från raderna ovan som finns i filen pg_hba.conf som vi kan från den medföljande frågan. Vid första anblicken ser det ut som om båda rollerna kan logga in.

Vi kommer att testa och bekräfta.

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 viktiga här är att även om nolog_user och log_user båda kan logga in enligt filen pg_hba.conf, är det bara log_user som faktiskt tillåts logga in.

Där log_user klarade åtkomstbegränsningarna på databasnivå (genom att ha LOGIN-attributet), gjorde det inte nolog_user.

Låt oss redigera log_users rad i filen pg_hba.conf och ändra databasnamnet som denna roll får åtkomst till. Här är ändringen, vilket indikerar att log_user nu endast kan logga in på testdatabasen.

local trial log_user password

Låt oss först försöka logga in på postgres-databasen, som log_user tidigare hade tillgång till på grund av all-flaggan.

$ 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 testdatabasen har log_user behörighet att

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

Inget fel där och trial=>-prompten visar den för närvarande anslutna databasen.

Dessa inställningar gäller även inom servermiljön, när en anslutning har upprättats.

Låt oss försöka ansluta till den postgres-databasen 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

Genom exemplen som presenteras här bör du vara medveten om anpassningsalternativen för rollerna i ditt kluster.

Obs! Ofta krävs att filen pg_hba.conf laddas om för att ändringar ska träda i kraft.

Använd verktyget pg_ctl för att ladda om din server.

Syntaxen skulle vara:

pg_ctl reload [-D datadir] [-s]

För att veta var din datakatalog finns kan du fråga pg_settings system VIEW, om du är inloggad som SUPERANVÄNDARE med en liknande SELECT-fråga som nedan.

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

Ge sedan ditt skal till postgres-användaren (eller annan SUPERANVÄNDARE) med:

$ sudo -u postgres bash

Såvida du inte har lagt till verktyget pg_ctl till din $PATH, måste du kvalificera det fullständigt för användning och sedan skicka kommandot för att köra, tillsammans med datadir-platsen.

Här är ett exempel:

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

Låt oss kontrollera serverns 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"

Aktiveringsbara takeaways

  • Roller måste uppfylla kraven från både pg_hba.conf-filen och åtkomstbehörigheter på databasnivå.
  • pg_hba.conf-filen kontrolleras uppifrån och ned för varje anslutningsbegäran. Ordningen i filen är betydande.

Databas-, tabell- och kolumnprivilegier och begränsningar - Skräddarsydda roller för uppgifter och ansvar

För att roller ska kunna använda databasobjekt (tabeller, vyer, kolumner, funktioner, etc...), måste de ges åtkomstbehörighet till dem.

Kommandot GRANT definierar dessa viktiga privilegier.

Vi kommer att gå över några exempel för att se kärnan i dess användning.

Skapa databaser

Eftersom log_user tilldelades attributen CREATEDB och CREATEROLE kan vi använda den här rollen för att skapa en testdatabas med namnet trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Förutom att skapa en ny ROLL:

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

Slutligen kommer log_user att ansluta till den nya testdatabasen:

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

Lägg märke till att uppmaningen ändrades till namnet "trial" vilket indikerar att vi är anslutna till den databasen.

Låt oss använda log_user för att SKAPA en låtsastabell.

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

Roll log_user skapade nyligen en hjälparroll, db_user. Vi kräver att db_user har begränsade privilegier för tabellen another_workload.

Utan tvekan bör kolumnen sensitive_info inte nås av denna roll. INSERT, UPDATE och DELETE-kommandon bör inte heller beviljas för närvarande, förrän db_user uppfyller vissa förväntningar.

Db_user krävs dock för att utfärda SELECT-frågor. Hur kan vi begränsa denna rolls förmåga i tabellen another_workload?

Låt oss först undersöka den exakta syntaxen som finns i PostgreSQL GRANT-kommandodokumenten, på tabellnivå.

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

Därefter implementerar vi kraven som anges för rollen db_user, med tillämpning av specifik syntax.

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

Lägg märke till att precis efter nyckelordet SELECT listade vi kolumnerna som db_user kan komma åt. Om db_user försöker SELECT-frågor i kolumnen sensitive_info eller något annat kommando för den delen, kommer dessa frågor inte att köras tills de ändras.

Med db_user inloggad kommer vi att omsätta detta i praktiken genom att försöka en SELECT-fråga för att returnera alla kolumner och poster från tabellen.

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

Kolumn sensitive_info ingår i denna fråga. Därför returneras inga poster till db_user.

Men db_user kan VÄLJA de tillåtna kolumnerna

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 fungerar bra.

Vi kommer också att testa kommandona INSERT, UPDATE och 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

Genom att inte tilldela kommandon INSERT, UPDATE eller DELETE till db_user nekas rollen åtkomst att använda dem.

Med de många tillgängliga alternativen är det praktiskt taget obegränsat att konfigurera din roll. Du kan göra dem fullt funktionella, kunna utföra alla kommandon eller så begränsade som dina krav kräver.

Aktiveringsbara takeaways

  • Roller ges åtkomstprivilegier till databasobjekt via GRANT-kommandot.
  • Databasobjekt och kommandon mot dessa objekt är mycket konfigurerbara inom PostgreSQL-miljön.

Stänger

Genom de här blogginläggens exempel bör du ha en bättre förståelse för:

  1. Skapa en roll med specifika attribut.
  2. Ställa in en fungerande anslutning mellan klienten och servern, vilket ger roller inloggningsåtkomst till databaser.
  3. Anpassa dina roller i hög grad för att möta individuella krav på databas-, tabell- och kolumnnivååtkomst genom att implementera nödvändiga attribut.

  1. Varför får jag PLS-00302:komponent måste deklareras när den finns?

  2. Varför behandlar Oracle 9i en tom sträng som NULL?

  3. Hur man skapar en ny användare och beviljar behörigheter i MySQL

  4. Hur man uppnår PCI-kompatibilitet för MySQL &MariaDB med ClusterControl - The Replay