PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Privilèges PostgreSQL et gestion des utilisateurs - Ce que vous devez savoir

La gestion des utilisateurs dans PostgreSQL peut être délicate. En règle générale, les nouveaux utilisateurs sont gérés, de concert, dans quelques zones clés de l'environnement. Souvent, les privilèges sont parfaits d'un côté, mais mal configurés de l'autre. Cet article de blog fournira des "trucs et astuces" pratiques pour un utilisateur ou un rôle, comme nous le connaîtrons, configuré dans PostgreSQL.

Les domaines sur lesquels nous nous concentrerons sont :

  • Les rôles de PostgreSQL

Vous découvrirez les rôles, les attributs de rôle, les meilleures pratiques pour nommer vos rôles et les configurations de rôle courantes.

  • Le fichier pg_hba.conf

Dans cette section, nous examinerons l'un des fichiers clés et ses paramètres, pour les connexions côté client et la communication avec le serveur.

  • Privilèges et restrictions au niveau de la base de données, des tables et des colonnes.

Vous cherchez à configurer des rôles pour des performances et une utilisation optimales ? Vos tables contiennent-elles des données sensibles, uniquement accessibles aux rôles privilégiés ? Pourtant, avec la nécessité de permettre à différents rôles d'effectuer un travail limité ? Ces questions et bien d'autres seront exposées dans cette section.

Les rôles de PostgreSQL :qu'est-ce qu'un "rôle" et comment en créer un ?

Les autorisations d'accès à la base de données dans PostgreSQL sont gérées avec le concept de rôle, qui s'apparente à un utilisateur. Les rôles peuvent également représenter des groupes d'utilisateurs dans l'écosystème PostgreSQL.

PostgreSQL établit la capacité des rôles à attribuer des privilèges aux objets de base de données qu'ils possèdent, permettant l'accès et les actions à ces objets. Les rôles ont la capacité d'accorder l'appartenance à un autre rôle. Les attributs fournissent des options de personnalisation, pour l'authentification client autorisée.

Les attributs des rôles via la commande CREATE ROLE sont disponibles dans la documentation officielle de PostgreSQL.

Vous trouverez ci-dessous les attributs que vous attribuerez généralement lors de la configuration d'un nouveau rôle. La plupart d'entre eux sont explicites. Cependant, une brève description est fournie pour dissiper toute confusion ainsi que des exemples d'utilisation.

SUPERUTILISATEUR - Un SUPERUTILISATEUR de base de données mérite une mise en garde. En bout de ligne, les rôles avec cet attribut peuvent créer un autre SUPERUSER. En fait, cet attribut est requis pour créer un autre rôle SUPERUSER. Étant donné que les rôles avec cet attribut contournent tous les contrôles d'autorisation, accordez ce privilège judicieusement.

CREATEDB - Permet au rôle de créer des bases de données.

CREATEROLE - Avec cet attribut, un rôle peut émettre la commande CREATE ROLE. Par conséquent, créez d'autres rôles.

CONNEXION - Permet de se connecter. Un nom de rôle avec cet attribut peut être utilisé dans la commande de connexion client. Plus de détails sur cet attribut avec des exemples à venir.

Certains attributs ont une commande nommée explicite opposée polaire et sont généralement la valeur par défaut lorsqu'ils ne sont pas spécifiés.

par exemple
SUPERUTILISATEUR | NOSUPERUSER
CREATEROLE |NOCREATEROLE
CONNEXION |NOLOGIN

Examinons certains de ces attributs en action pour diverses configurations que vous pouvez configurer pour commencer.

Créer et supprimer des rôles

Créer un rôle est relativement simple. Voici un exemple rapide :

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

Qu'est-ce qui n'allait pas là-bas ? Il s'avère que les noms de rôle ne peuvent pas commencer par autre chose qu'une lettre.

"Et si on enveloppait le nom de guillemets doubles ?" Voyons :

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

Cela a fonctionné, mais probablement pas une bonne idée. Que diriez-vous d'un caractère spécial au milieu du nom ?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Pas de problème là-bas. Même sans guillemets doubles, aucune erreur n'a été renvoyée.

Je n'aime tout simplement pas la structure du nom de $money_man pour un utilisateur. Je te laisse $money_man et je recommence. La commande DROP ROLE se charge de supprimer un rôle. Le voici en cours d'utilisation.

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

Et une autre erreur avec le rôle $money_man. Encore une fois, recourir aux guillemets doubles.

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

Le privilège LOGIN

Examinons deux utilisateurs différents, l'un avec le privilège LOGIN et l'autre sans. Je leur attribuerai également des mots de passe.

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

Remarque :Les mots de passe fournis pour les rôles fictifs ci-dessus sont uniquement à des fins de démonstration. Vous devez toujours vous efforcer de fournir des mots de passe uniques et renforcés lors de la mise en œuvre des rôles. Bien qu'un mot de passe soit mieux que pas de mot de passe, un mot de passe renforcé est encore mieux qu'un mot de passe trivial.

Attribuons à log_user les attributs CREATEDB et CREATEROLE avec la commande ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Vous pouvez vérifier ces attributs définis en vérifiant le catalogue pg_role. Deux colonnes intéressantes sont rolcreaterole et rolcreatedb. Les deux sont du type de données booléen, ils doivent donc être définis sur t pour true pour ces attributs.

Confirmez avec une requête SELECT similaire.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Téléchargez le livre blanc aujourd'hui PostgreSQL Management &Automation with ClusterControlDécouvrez ce que vous devez savoir pour déployer, surveiller, gérer et faire évoluer PostgreSQLTélécharger le livre blanc

Comment pouvez-vous déterminer les rôles existants présents dans la base de données ?

Deux méthodes disponibles sont la commande psql \du ou la sélection dans le catalogue pg_roles.

Ici, ils sont tous les deux utilisés.

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)

Connexion

Donnons aux deux rôles la possibilité de se connecter au serveur.

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

Pour résoudre ce problème, nous devons creuser dans ce fichier pg_hba.conf. La solution est discutée au fur et à mesure que nous continuons dans cet article, dans cette section spécifique.

Conseils exploitables

  • CREATE ROLE et son équivalent, DROP ROLE, sont vos commandes incontournables pour implémenter et supprimer des rôles.
  • ALTER ROLE gère la modification des attributs d'un rôle.
  • Les rôles sont valides dans toutes les bases de données en raison de la définition au niveau du cluster de base de données.
  • Gardez à l'esprit que la création d'un nom de rôle commençant par un caractère spécial vous oblige à "l'adresser" avec des guillemets doubles.
  • Les rôles et leurs privilèges sont établis à l'aide d'attributs.
  • Pour établir des rôles nécessitant l'attribut LOGIN par défaut, CREATE USER est une commande facultative à votre disposition. Utilisés à la place de CREATE ROLE nom_rôle LOGIN, ils sont essentiellement égaux.

Le fichier pg_hba.conf - Établir un terrain d'entente entre le serveur et le client

Couvrir tous les aspects et paramètres du fichier pg_hba.conf dans un seul article de blog serait au mieux intimidant. Au lieu de cela, cette section présentera les pièges courants que vous pourriez rencontrer et les solutions pour y remédier.

Des connexions réussies nécessitent un effort conjoint des deux parties dans leur ensemble. Les rôles se connectant au serveur doivent toujours respecter les restrictions d'accès définies au niveau de la base de données, après avoir passé les paramètres dans le fichier pg_hba.conf.

Des exemples pertinents de cette relation sont inclus au fur et à mesure que cette section progresse.

Pour localiser votre fichier pg_hba.conf, lancez une requête SELECT similaire sur la VUE pg_settings. Vous devez être connecté en tant que SUPERUTILISATEUR pour interroger cette VUE.

postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

Le fichier pg_hba.conf contient des enregistrements spécifiant l'un des sept formats disponibles pour une demande de connexion donnée. Voir le spectre complet ici .

Dans le cadre de cet article de blog, nous examinerons les paramètres que vous pouvez utiliser pour un environnement local.

Peut-être que ce serveur est pour votre apprentissage et votre étude continus (comme le mien).

Je dois noter en particulier que ces paramètres ne sont pas les paramètres optimaux pour un système renforcé contenant plusieurs utilisateurs.

Les champs pour ce type de connexion sont :

local database user auth-method [auth-options]

Où ils signifient :

local - les connexions sont tentées avec des sockets de domaine Unix.

base de données - Spécifie la ou les bases de données nommées pour cette correspondance d'enregistrement.

user - Le nom d'utilisateur de la base de données correspondant à cet enregistrement. Une liste séparée par des virgules de plusieurs utilisateurs ou de tous est également autorisée pour ce champ.

auth-method - Est utilisé lorsqu'une connexion correspond à cet enregistrement unique. Les choix possibles pour ce champ sont :

  • confiance
  • rejeter
  • scram-sha-256
  • md5
  • mot de passe
  • gss
  • sspi
  • identifier
  • pair
  • ldap
  • rayon
  • certificat
  • pam
  • bsd

Les lignes définies dans le fichier pg_hba.conf pour les rôles nolog_user et log_user ressemblent à ceci :

local all nolog_user password
local all log_user password

Remarque :étant donné que le mot de passe est envoyé en texte clair, il ne doit pas être utilisé dans des environnements non fiables avec des réseaux non fiables.

Examinons trois colonnes intéressantes de la vue pg_hba_file_rules avec la requête ci-dessous. Encore une fois, votre rôle a besoin de l'attribut SUPERUSER pour interroger cette VUE.

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)

Nous pouvons voir des informations identiques à partir des lignes fournies ci-dessus trouvées dans le fichier pg_hba.conf comme nous le pouvons à partir de la requête qui l'accompagne. À première vue, il semble que les deux rôles peuvent se connecter.

Nous allons tester et confirmer.

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

Le point clé ici est que, bien que nolog_user et log_user soient tous deux capables de se connecter selon le fichier pg_hba.conf, seul log_user est autorisé à se connecter.

Là où log_user a passé les restrictions d'accès au niveau de la base de données (en ayant l'attribut LOGIN), nolog_user ne l'a pas fait.

Modifions la ligne de log_user dans le fichier pg_hba.conf et changeons le nom de la base de données auquel ce rôle est autorisé à accéder. Voici le changement, indiquant que log_user peut désormais se connecter uniquement à la base de données d'essai.

local trial log_user password

Essayons d'abord de nous connecter à la base de données postgres, à laquelle log_user avait précédemment accès en raison de l'indicateur all.

$ 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

Maintenant, avec la base de données d'essai, log_user a le privilège de

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

Aucune erreur ici et l'invite trial=> affiche la base de données actuellement connectée.

Ces paramètres s'appliquent également dans l'environnement du serveur, une fois la connexion établie.

Essayons à nouveau de nous connecter à cette base de données postgres :

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

Grâce aux exemples présentés ici, vous devez connaître les options de personnalisation des rôles dans votre cluster.

Remarque :Il est souvent nécessaire de recharger le fichier pg_hba.conf pour que les modifications prennent effet.

Utilisez l'utilitaire pg_ctl pour recharger votre serveur.

La syntaxe serait :

pg_ctl reload [-D datadir] [-s]

Pour savoir où se trouve votre répertoire de données, vous pouvez interroger le système VIEW de pg_settings, si vous êtes connecté en tant que SUPERUSER avec une requête SELECT similaire à celle ci-dessous.

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

Ensuite, donnez votre shell à l'utilisateur postgres (ou à un autre SUPERUTILISATEUR) avec :

$ sudo -u postgres bash

À moins que vous n'ayez ajouté l'utilitaire pg_ctl à votre $PATH, vous devez le qualifier complètement pour l'utiliser, puis passer la commande à exécuter, ainsi que l'emplacement datadir.

Voici un exemple :

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

Vérifions l'état du serveur avec :

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

Conseils exploitables

  • Les rôles doivent satisfaire aux exigences du fichier pg_hba.conf et des privilèges d'accès au niveau de la base de données.
  • Le fichier pg_hba.conf est vérifié de haut en bas, pour chaque demande de connexion. L'ordre dans le fichier est important.

Privilèges et restrictions de base de données, de table et de colonne – Rôles adaptés aux tâches et aux responsabilités

Pour que les rôles utilisent les objets de la base de données (tables, vues, colonnes, fonctions, etc.), ils doivent disposer de privilèges d'accès à ceux-ci.

La commande GRANT définit ces privilèges essentiels.

Nous allons passer en revue quelques exemples pour comprendre l'essence de son utilisation.

Créer des bases de données

Étant donné que log_user a reçu les attributs CREATEDB et CREATEROLE, nous pouvons utiliser ce rôle pour créer une base de données de test nommée trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

En plus de créer un nouveau RÔLE :

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

Enfin, log_user se connectera à la nouvelle base de données d'essai :

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

Notez que l'invite a été remplacée par le nom "essai" indiquant que nous sommes connectés à cette base de données.

Utilisons log_user pour CRÉER une table fictive.

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

Le rôle log_user a récemment créé un rôle d'assistance, db_user. Nous exigeons que db_user ait des privilèges limités pour la table another_workload.

Sans aucun doute, la colonne sensitive_info ne devrait pas être accessible par ce rôle. Les commandes INSERT, UPDATE et DELETE ne doivent pas non plus être accordées pour le moment, jusqu'à ce que db_user réponde à certaines attentes.

Cependant, db_user est requis pour émettre des requêtes SELECT. Comment pouvons-nous limiter les capacités de ces rôles dans la table another_workload ?

Examinons d'abord la syntaxe exacte trouvée dans la documentation de la commande PostgreSQL GRANT, au niveau de la table.

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

Ensuite, nous implémentons les exigences définies pour le rôle db_user, en appliquant une syntaxe spécifique.

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

Remarquez juste après le mot-clé SELECT, nous avons listé les colonnes auxquelles db_user peut accéder. Jusqu'à modification, si db_user tente des requêtes SELECT sur la colonne sensitive_info, ou toute autre commande d'ailleurs, ces requêtes ne seront pas exécutées.

Avec db_user connecté, nous allons mettre cela en pratique, en essayant une requête SELECT pour renvoyer toutes les colonnes et tous les enregistrements de la table.

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

La colonne sensitive_info est incluse dans cette requête. Par conséquent, aucun enregistrement n'est renvoyé à db_user.

Mais db_user peut SÉLECTIONNER les colonnes autorisées

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)

Cela fonctionne très bien.

Nous testerons également les commandes INSERT, UPDATE et 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

En n'affectant pas les commandes INSERT, UPDATE ou DELETE à db_user, le rôle se voit refuser l'accès à leur utilisation.

Avec la pléthore d'options disponibles, la configuration de votre rôle est pratiquement illimitée. Vous pouvez les rendre entièrement fonctionnels, capables d'exécuter n'importe quelle commande ou aussi limités que vos besoins l'exigent.

Conseils exploitables

  • Les rôles reçoivent des privilèges d'accès aux objets de la base de données via la commande GRANT.
  • Les objets de la base de données et les commandes associées à ces objets sont hautement configurables dans l'environnement PostgreSQL.

Fermeture

Grâce aux exemples fournis dans cet article de blog, vous devriez mieux comprendre :

  1. Création d'un rôle avec des attributs spécifiques.
  2. Définition d'une connexion fonctionnelle entre le client et le serveur, permettant aux rôles d'accéder aux bases de données.
  3. Personnaliser fortement vos rôles pour répondre aux exigences individuelles d'accès au niveau de la base de données, des tables et des colonnes en mettant en œuvre les attributs nécessaires.