Die Benutzerverwaltung in PostgreSQL kann schwierig sein. Typischerweise werden neue Benutzer zusammen innerhalb einiger wichtiger Bereiche in der Umgebung verwaltet. Oftmals sind Privilegien auf der einen Seite perfekt, auf der anderen Seite jedoch falsch konfiguriert. Dieser Blogbeitrag bietet praktische „Tipps und Tricks“ für einen Benutzer oder eine Rolle, wie wir sie kennen werden, die in PostgreSQL eingerichtet wird.
Die Themenbereiche, auf die wir uns konzentrieren werden, sind:
- Rollen übernehmen von PostgreSQL
Sie erfahren mehr über Rollen, Rollenattribute, Best Practices für die Benennung Ihrer Rollen und allgemeine Rolleneinstellungen.
- Die pg_hba.conf-Datei
In diesem Abschnitt betrachten wir eine der Schlüsseldateien und ihre Einstellungen für clientseitige Verbindungen und die Kommunikation mit dem Server.
- Berechtigungen und Einschränkungen auf Datenbank-, Tabellen- und Spaltenebene.
Möchten Sie Rollen für optimale Leistung und Nutzung konfigurieren? Enthalten Ihre Tabellen sensible Daten, auf die nur privilegierte Rollen zugreifen können? Doch mit der Notwendigkeit, unterschiedliche Rollen zuzulassen, um begrenzte Arbeit zu leisten? Diese und weitere Fragen werden in diesem Abschnitt behandelt.
Die Übernahme von Rollen durch PostgreSQL – Was ist eine „Rolle“ und wie erstellt man eine?
Berechtigungen für den Datenbankzugriff innerhalb von PostgreSQL werden mit dem Konzept einer Rolle gehandhabt, die mit einem Benutzer verwandt ist. Rollen können auch Benutzergruppen im PostgreSQL-Ökosystem darstellen.
PostgreSQL schafft die Möglichkeit für Rollen, Datenbankobjekten, deren Eigentümer sie sind, Berechtigungen zuzuweisen, wodurch der Zugriff und die Aktionen für diese Objekte ermöglicht werden. Rollen können einer anderen Rolle die Mitgliedschaft gewähren. Attribute bieten Anpassungsoptionen für die zulässige Client-Authentifizierung.
Attribute für Rollen über den Befehl CREATE ROLE sind in der offiziellen PostgreSQL-Dokumentation verfügbar.
Nachfolgend sind die Attribute aufgeführt, die Sie normalerweise beim Einrichten einer neuen Rolle zuweisen. Die meisten davon sind selbsterklärend. Es wird jedoch eine kurze Beschreibung bereitgestellt, um Verwirrung zu beseitigen, zusammen mit Anwendungsbeispielen.
SUPERUSER - Ein Datenbank-SUPERUSER verdient ein Wort der Vorsicht. Unterm Strich können Rollen mit diesem Attribut einen weiteren SUPERUSER erstellen. Tatsächlich wird dieses Attribut benötigt, um eine weitere SUPERUSER-Rolle zu erstellen. Da Rollen mit diesem Attribut alle Berechtigungsprüfungen umgehen, gewähren Sie dieses Privileg mit Bedacht.
CREATEDB – Ermöglicht der Rolle, Datenbanken zu erstellen.
CREATEROLE – Mit diesem Attribut kann eine Rolle den Befehl CREATE ROLE ausgeben. Erstellen Sie daher andere Rollen.
LOGIN - Aktiviert die Möglichkeit, sich anzumelden. Ein Rollenname mit diesem Attribut kann im Client-Verbindungsbefehl verwendet werden. Weitere Details zu diesem Attribut mit in Kürze erscheinenden Beispielen.
Bestimmte Attribute haben einen expliziten entgegengesetzten benannten Befehl und sind normalerweise der Standardwert, wenn sie nicht angegeben werden.
B.
SUPERUSER | NOSUPERUSER
CREATEROLE |NOCREATEROLE
LOGIN |NOLOGIN
Sehen wir uns einige dieser Attribute in Aktion für verschiedene Konfigurationen an, die Sie einrichten können, um loszulegen.
Rollen erstellen und löschen
Das Erstellen einer Rolle ist relativ einfach. Hier ist ein kurzes Beispiel:
postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;
Was ist da schief gelaufen? Es stellt sich heraus, dass Rollennamen nicht mit etwas anderem als einem Buchstaben beginnen können.
"Was ist mit dem Einschließen des Namens in doppelte Anführungszeichen?" Mal sehen:
postgres=# CREATE ROLE "$money_man";
CREATE ROLE
Das hat funktioniert, wenn auch wahrscheinlich keine gute Idee. Wie wäre es mit einem Sonderzeichen mitten im Namen?
postgres=# CREATE ROLE money$_man;
CREATE ROLE
Kein Problem dort. Auch ohne doppelte Anführungszeichen wurde kein Fehler zurückgegeben.
Ich mag die Namensstruktur von $money_man für einen Benutzer einfach nicht. Ich lasse dich fallen $money_man und fange neu an. Der Befehl DROP ROLE kümmert sich um das Entfernen einer Rolle. Hier wird es verwendet.
postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;
Und ein weiterer Fehler mit der $money_man-Rolle. Wiederum auf die doppelten Anführungszeichen zurückgreifen.
postgres=# DROP ROLE "$money_man";
DROP ROLE
Das LOGIN-Privileg
Schauen wir uns zwei verschiedene Benutzer an, einen mit LOGIN-Privileg und einen ohne. Ich werde ihnen auch Passwörter zuweisen.
postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE
Hinweis:Die für die obigen fiktiven Rollen bereitgestellten Passwörter dienen nur zu Demonstrationszwecken. Sie sollten sich bei der Implementierung von Rollen immer bemühen, eindeutige und gehärtete Kennwörter bereitzustellen. Während ein Passwort besser ist als kein Passwort, ist ein gehärtetes Passwort sogar besser als ein triviales.
Weisen wir log_user die Attribute CREATEDB und CREATEROLE mit dem Befehl ALTER ROLE zu.
postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE
Sie können diese festgelegten Attribute überprüfen, indem Sie den pg_role-Katalog überprüfen. Zwei interessante Spalten sind rolcreaterole und rolcreatedb. Beide sind vom Datentyp Boolean, also sollten sie für diese Attribute auf t für true gesetzt werden.
Bestätigen Sie mit einer ähnlichen SELECT-Abfrage.
postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb
---------------+-------------
t | t
(1 row)
Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunter Wie können Sie die vorhandenen Rollen in der Datenbank ermitteln?
Zwei verfügbare Methoden sind der Befehl psql \du oder die Auswahl aus dem pg_roles-Katalog.
Hier werden beide verwendet.
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)
Einloggen
Lassen Sie uns beiden Rollen die Möglichkeit geben, sich beim Server anzumelden.
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
Um dieses Problem zu lösen, müssen wir uns mit dieser pg_hba.conf-Datei befassen. Die Lösung wird diskutiert, während wir in diesem Beitrag zu diesem speziellen Abschnitt fortfahren.
Umsetzbare Erkenntnisse
- CREATE ROLE und sein Gegenstück DROP ROLE sind Ihre bevorzugten Befehle zum Implementieren und Entfernen von Rollen.
- ALTER ROLE behandelt das Ändern der Attribute einer Rolle.
- Rollen sind aufgrund der Definition auf Datenbank-Cluster-Ebene in allen Datenbanken gültig.
- Denken Sie daran, dass Sie einen Rollennamen, der mit einem Sonderzeichen beginnt, mit doppelten Anführungszeichen "adressieren" müssen.
- Rollen und ihre Privilegien werden mithilfe von Attributen eingerichtet.
- Um Rollen einzurichten, die standardmäßig das LOGIN-Attribut benötigen, steht Ihnen CREATE USER als optionaler Befehl zur Verfügung. Anstelle von CREATE ROLE Rollenname LOGIN verwendet, sind sie im Wesentlichen gleich.
Die pg_hba.conf-Datei - Herstellen einer gemeinsamen Basis zwischen dem Server und dem Client
Alle Aspekte und Einstellungen für die Datei pg_hba.conf in einem einzigen Blogbeitrag abzudecken, wäre bestenfalls entmutigend. Stattdessen werden in diesem Abschnitt häufig auftretende Fallstricke und Lösungen zu deren Behebung vorgestellt.
Erfolgreiche Verbindungen erfordern eine gemeinsame Anstrengung beider Teile als Ganzes. Rollen, die sich mit dem Server verbinden, müssen weiterhin Zugriffsbeschränkungen erfüllen, die auf Datenbankebene festgelegt wurden, nachdem sie die Einstellungen in der Datei pg_hba.conf übergeben haben.
Relevante Beispiele für diese Beziehung werden im Verlauf dieses Abschnitts hinzugefügt.
Um Ihre pg_hba.conf-Datei zu finden, geben Sie eine ähnliche SELECT-Abfrage in der Ansicht pg_settings ein. Sie müssen als SUPERUSER angemeldet sein, um diese VIEW abzufragen.
postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)
Die Datei pg_hba.conf enthält Datensätze, die eines von sieben verfügbaren Formaten für eine bestimmte Verbindungsanforderung angeben. Sehen Sie hier das gesamte Spektrum .
Zum Zweck dieses Blogposts werden wir uns die Einstellungen ansehen, die Sie für eine lokale Umgebung verwenden können.
Vielleicht ist dieser Server für Ihr weiteres Lernen und Studieren (so wie meiner).
Ich muss besonders darauf hinweisen, dass diese Einstellungen nicht die optimalen Einstellungen für ein gehärtetes System mit mehreren Benutzern sind.
Die Felder für diesen Verbindungstyp sind:
local database user auth-method [auth-options]
Wo sie bedeuten:
local - Verbindungen werden mit Unix-Domänen-Sockets versucht.
database - Gibt die Datenbank(en) an, die für diese Datensatzübereinstimmung benannt wurden.
user – Der Datenbank-Benutzername, der mit diesem Datensatz übereinstimmt. Eine durch Kommas getrennte Liste mit mehreren Benutzern oder allen ist für dieses Feld ebenfalls zulässig.
auth-method – Wird verwendet, wenn eine Verbindung mit diesem eindeutigen Datensatz übereinstimmt. Die Auswahlmöglichkeiten für dieses Feld sind:
- Vertrauen
- ablehnen
- scram-sha-256
- md5
- Passwort
- gss
- spi
- ident
- Kollege
- LDAP
- Radius
- Zertifikat
- Pam
- BSD
Die Zeilen in der Datei pg_hba.conf für die Rollen nolog_user und log_user sehen folgendermaßen aus:
local all nolog_user password
local all log_user password
Hinweis:Da das Passwort im Klartext gesendet wird, sollte es nicht in nicht vertrauenswürdigen Umgebungen mit nicht vertrauenswürdigen Netzwerken verwendet werden.
Sehen wir uns drei interessante Spalten aus der Ansicht pg_hba_file_rules mit der folgenden Abfrage an. Auch hier benötigt Ihre Rolle das SUPERUSER-Attribut, um diese VIEW abzufragen.
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)
Wir können identische Informationen aus den oben bereitgestellten Zeilen in der Datei pg_hba.conf sehen wie aus der begleitenden Abfrage. Auf den ersten Blick sieht es so aus, als ob sich beide Rollen anmelden können.
Wir werden testen und bestätigen.
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=>
Der entscheidende Punkt hier ist, dass sich nolog_user und log_user zwar beide gemäß der pg_hba.conf-Datei anmelden können, aber nur log_user sich tatsächlich anmelden darf.
Wo log_user die Zugriffsbeschränkungen auf Datenbankebene bestanden hat (durch das LOGIN-Attribut), hat nolog_user dies nicht getan.
Lassen Sie uns die Zeile von log_user in der Datei pg_hba.conf bearbeiten und den Datenbanknamen ändern, auf den diese Rolle zugreifen darf. Hier ist die Änderung, die anzeigt, dass log_user sich jetzt nur bei der Testdatenbank anmelden kann.
local trial log_user password
Versuchen wir zunächst, uns bei der Postgres-Datenbank anzumelden, auf die log_user zuvor aufgrund des all-Flags Zugriff hatte.
$ 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
Mit der Testdatenbank hat log_user jetzt die Berechtigung zum
$ psql -U log_user -W trial
Password for user log_user:
psql (10.1)
Type "help" for help.
trial=>
Es gibt keinen Fehler und die Eingabeaufforderung "trial=>" zeigt die aktuell verbundene Datenbank an.
Diese Einstellungen gelten auch innerhalb der Serverumgebung, sobald eine Verbindung hergestellt ist.
Versuchen wir erneut, eine Verbindung zu dieser Postgres-Datenbank herzustellen:
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
Durch die hier vorgestellten Beispiele sollten Sie sich der Anpassungsoptionen für die Rollen in Ihrem Cluster bewusst sein.
Hinweis:Häufig ist ein erneutes Laden der Datei pg_hba.conf erforderlich, damit die Änderungen wirksam werden.
Verwenden Sie das Dienstprogramm pg_ctl, um Ihren Server neu zu laden.
Die Syntax wäre:
pg_ctl reload [-D datadir] [-s]
Um zu wissen, wo sich Ihr Datenverzeichnis befindet, können Sie das pg_settings-System VIEW abfragen, wenn Sie als SUPERUSER mit einer ähnlichen SELECT-Abfrage wie unten eingeloggt sind.
postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
setting
-----------------------------
/var/lib/postgresql/10/main
(1 row)
Geben Sie dann Ihre Shell an den postgres-Benutzer (oder einen anderen SUPERUSER) mit:
$ sudo -u postgres bash
Sofern Sie das Dienstprogramm pg_ctl nicht zu Ihrem $PATH hinzugefügt haben, müssen Sie es vollständig für die Verwendung qualifizieren und dann den auszuführenden Befehl zusammen mit dem Speicherort des Datenverzeichnisses übergeben.
Hier ist ein Beispiel:
$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled
Lassen Sie uns den Status des Servers überprüfen mit:
$ /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"
Umsetzbare Erkenntnisse
- Rollen müssen sowohl die Anforderungen der Datei pg_hba.conf als auch die Zugriffsberechtigungen auf Datenbankebene erfüllen.
- Die Datei pg_hba.conf wird bei jeder Verbindungsanforderung von oben nach unten geprüft. Die Reihenfolge in der Datei ist wichtig.
Datenbank-, Tabellen- und Spaltenprivilegien und -beschränkungen – passgenaue Rollen für Aufgaben und Verantwortlichkeiten
Damit Rollen Datenbankobjekte (Tabellen, Ansichten, Spalten, Funktionen usw.) verwenden können, müssen ihnen Zugriffsrechte für diese gewährt werden.
Der GRANT-Befehl definiert diese wesentlichen Privilegien.
Wir werden einige Beispiele durchgehen, um die Essenz seiner Verwendung zu verstehen.
Datenbanken erstellen
Da log_user die Attribute CREATEDB und CREATEROLE zugewiesen wurden, können wir diese Rolle verwenden, um eine Testdatenbank namens trial.
zu erstellenpostgres=> CREATE DATABASE trial:
CREATE DATABASE
Zusätzlich zum Erstellen einer neuen ROLE:
postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE
Schließlich verbindet sich log_user mit der neuen Testdatenbank:
postgres=> \c trial;
Password for user log_user:
You are now connected to database "trial" as user "log_user".
trial=>
Beachten Sie, dass die Eingabeaufforderung in den Namen „trial“ geändert wurde, was anzeigt, dass wir mit dieser Datenbank verbunden sind.
Lassen Sie uns log_user verwenden, um eine Scheintabelle zu ERSTELLEN.
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 hat kürzlich eine Hilfsrolle, db_user, erstellt. Wir verlangen, dass db_user eingeschränkte Berechtigungen für die Tabelle another_workload hat.
Zweifellos sollte diese Rolle nicht auf die Spalte sensitive_info zugreifen. INSERT-, UPDATE- und DELETE-Befehle sollten zu diesem Zeitpunkt ebenfalls nicht gewährt werden, bis db_user bestimmte Erwartungen erfüllt.
db_user ist jedoch erforderlich, um SELECT-Abfragen zu stellen. Wie können wir die Fähigkeiten dieser Rolle innerhalb der Tabelle another_workload einschränken?
Lassen Sie uns zuerst die genaue Syntax untersuchen, die in der PostgreSQL GRANT-Befehlsdokumentation auf Tabellenebene zu finden ist.
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
Als Nächstes implementieren wir die für die Rolle db_user festgelegten Anforderungen unter Anwendung einer bestimmten Syntax.
trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT
Beachten Sie, dass wir direkt nach dem Schlüsselwort SELECT die Spalten aufgelistet haben, auf die db_user zugreifen kann. Sollte db_user bis zur Änderung SELECT-Abfragen in der Spalte sensitive_info oder irgendeinen anderen Befehl versuchen, werden diese Abfragen nicht ausgeführt.
Wenn db_user angemeldet ist, werden wir dies in die Praxis umsetzen und versuchen, eine SELECT-Abfrage auszuführen, um alle Spalten und Datensätze aus der Tabelle zurückzugeben.
trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload
Die Spalte sensitive_info ist in dieser Abfrage enthalten. Daher werden keine Datensätze an db_user zurückgegeben.
Aber db_user kann die zulässigen Spalten AUSWÄHLEN
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)
Das funktioniert prima.
Wir werden auch die Befehle INSERT, UPDATE und DELETE testen.
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
Wenn Sie db_user keine INSERT-, UPDATE- oder DELETE-Befehle zuweisen, wird der Rolle der Zugriff auf deren Verwendung verweigert.
Mit der Fülle an verfügbaren Optionen ist die Konfiguration Ihrer Rolle praktisch grenzenlos. Sie können sie voll funktionsfähig machen, jeden Befehl ausführen oder so einschränken, wie es Ihre Anforderungen erfordern.
Umsetzbare Erkenntnisse
- Rollen erhalten Zugriffsrechte auf Datenbankobjekte über den GRANT-Befehl.
- Datenbankobjekte und Befehle für diese Objekte sind innerhalb der PostgreSQL-Umgebung hochgradig konfigurierbar.
Schließen
Durch die in diesem Blogbeitrag bereitgestellten Beispiele sollten Sie Folgendes besser verstehen:
- Erstellen einer Rolle mit bestimmten Attributen.
- Einrichten einer funktionierenden Verbindung zwischen dem Client und dem Server, wodurch Rollen-Login-Zugriff auf Datenbanken ermöglicht wird.
- Hochgradige Anpassung Ihrer Rollen, um individuelle Anforderungen für den Zugriff auf Datenbank-, Tabellen- und Spaltenebene zu erfüllen, indem die erforderlichen Attribute implementiert werden.