Dans un système de gestion de base de données (SGBD), les contrôles d'accès basés sur les rôles (RBAC) constituent une restriction des ressources de la base de données basée sur un ensemble de groupes de privilèges prédéfinis et sont devenus l'un des principaux méthodes de contrôle d'accès avancé. Des rôles de base de données peuvent être créés et supprimés, ainsi que des privilèges qui leur sont accordés et révoqués. Les rôles peuvent être accordés et révoqués à partir de comptes d'utilisateurs individuels. Les rôles actifs applicables pour un compte peuvent être sélectionnés parmi ceux accordés au compte et modifiés au cours des sessions pour ce compte.
Dans cet article de blog, nous couvrirons quelques trucs et astuces sur l'utilisation du rôle de base de données pour gérer les privilèges des utilisateurs et comme mécanisme de contrôle d'accès avancé pour l'accès à notre base de données. Si vous souhaitez en savoir plus sur les bases des rôles dans MySQL et MariaDB, consultez cet article de blog, Database User Management :Managing Roles for MariaDB.
Rôles MySQL vs MariaDB
MySQL et MariaDB utilisent deux mécanismes de rôle différents. Dans MySQL 8.0 et versions ultérieures, le rôle est similaire à un autre utilisateur, avec nom d'utilisateur et hôte ('role1'@'localhost'). Oui, c'est le nom du rôle, qui est pratiquement similaire à la définition standard utilisateur-hôte. MySQL stocke la définition du rôle tout comme le stockage des privilèges utilisateur dans la table système mysql.user.
MariaDB avait introduit les privilèges de rôle et d'accès dans MariaDB version 10.0.5 (novembre 2013), bien 8 ans avant que MySQL n'inclue cette fonctionnalité dans MySQL8.0. Il suit une gestion des rôles similaire dans un système de base de données compatible SQL, plus robuste et beaucoup plus facile à comprendre. MariaDB stocke la définition dans la table système mysql.user marquée avec une colonne nouvellement ajoutée appelée is_role. MySQL stocke le rôle différemment, en utilisant une combinaison utilisateur-hôte similaire à la gestion des utilisateurs MySQL standard.
Cela dit, la migration des rôles entre ces deux SGBD est désormais incompatible l'une avec l'autre.
Rôles d'administration et de sauvegarde de MariaDB
MySQL dispose de privilèges dynamiques, qui fournissent un ensemble de privilèges pour les tâches d'administration courantes. Pour MariaDB, nous pouvons définir des choses similaires en utilisant des rôles, en particulier pour les privilèges de sauvegarde et de restauration. Pour MariaDB Backup, puisqu'il s'agit d'une sauvegarde physique et nécessite un ensemble de privilèges différent, nous pouvons créer un rôle spécifique pour qu'il soit attribué à un autre utilisateur de la base de données.
Tout d'abord, créez un rôle et attribuez-lui les bons privilèges :
MariaDB> CREATE ROLE mariadb_backup;
MariaDB> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO mariadb_backup;
Nous pouvons ensuite créer l'utilisateur de sauvegarde, lui attribuer le rôle mariadb_backup et lui attribuer le rôle par défaut :
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'passw0rdMMM';
MariaDB> GRANT mariadb_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mariadb_backup FOR [email protected];
Pour mysqldump ou mariadb-dump, les privilèges minimaux pour créer une sauvegarde peuvent être définis comme ci-dessous :
MariaDB> CREATE ROLE mysqldump_backup;
MariaDB> GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON *.* TO mysqldump_backup;
Nous pouvons ensuite créer l'utilisateur de sauvegarde, lui attribuer le rôle mysqldump_backup et lui attribuer le rôle par défaut :
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_backup FOR [email protected];
Pour la restauration, cela nécessite généralement un ensemble de privilèges différent, ce qui est un peu :
MariaDB> CREATE ROLE mysqldump_restore;
MariaDB> GRANT SUPER, ALTER, INSERT, CREATE, DROP, LOCK TABLES, REFERENCES, SELECT, CREATE ROUTINE, TRIGGER ON *.* TO mysqldump_restore;
Nous pouvons ensuite créer l'utilisateur de restauration, lui attribuer le rôle mysqldump_restore et lui attribuer le rôle par défaut :
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_restore TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_restore FOR [email protected];
En utilisant cette astuce, nous pouvons simplifier le processus de création d'un utilisateur administratif en attribuant un rôle avec des privilèges prédéfinis. Ainsi, notre déclaration GRANT peut être raccourcie et facile à comprendre.
Création d'un rôle sur un rôle dans MariaDB
Nous pouvons créer un autre rôle sur un rôle existant similaire à une appartenance à un groupe imbriqué avec un contrôle plus précis des privilèges. Par exemple, nous pourrions créer les 4 rôles suivants :
MariaDB> CREATE ROLE app_developer, app_reader, app_writer, app_structure;
Accordez les privilèges pour gérer la structure du schéma au rôle app_structure :
MariaDB> GRANT CREATE, ALTER, DROP, CREATE VIEW, CREATE ROUTINE, INDEX, TRIGGER, REFERENCES ON app.* to app_structure;
Accordez les privilèges pour le langage de manipulation de données (DML) au rôle app_writer :
MariaDB> GRANT INSERT, DELETE, UPDATE, CREATE TEMPORARY TABLES app.* to app_writer;
Accordez les privilèges pour Data Query Language (DQL) au rôle app_reader :
MariaDB> GRANT SELECT, LOCK TABLES, SHOW VIEW app.* to app_reader;
Et enfin, nous pouvons attribuer tous les rôles ci-dessus à app_developer qui devrait avoir un contrôle total sur le schéma :
MariaDB> GRANT app_structure TO app_developer;
MariaDB> GRANT app_reader TO app_developer;
MariaDB> GRANT app_writer TO app_developer;
Les rôles sont prêts et nous pouvons maintenant créer un utilisateur de base de données avec le rôle app_developer :
MariaDB> CREATE USER 'michael'@'192.168.0.%' IDENTIFIED BY 'passw0rdMMMM';
MariaDB> GRANT app_developer TO 'michael'@'192.168.0.%';
MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
Étant donné que Michael appartient désormais aux rôles app_deleloper et app_reader, nous pouvons également lui attribuer les privilèges les plus bas comme rôle par défaut pour le protéger contre les erreurs humaines indésirables :
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
La bonne chose à propos de l'utilisation d'un rôle est que vous pouvez masquer les privilèges réels de l'utilisateur de la base de données. Considérez l'utilisateur de base de données suivant qui vient de se connecter :
MariaDB> SELECT user();
+----------------------+
| user() |
+----------------------+
| [email protected] |
+----------------------+
Lorsqu'il essayait de récupérer les privilèges à l'aide de SHOW GRANTS, Michael voyait :
MariaDB> SHOW GRANTS FOR 'michael'@'192.168.0.%';
+----------------------------------------------------------------------------------------------------------------+
| Grants for [email protected] |
+----------------------------------------------------------------------------------------------------------------+
| GRANT `app_developer` TO `michael`@`localhost` |
| GRANT USAGE ON *.* TO `michael`@`localhost` IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
+----------------------------------------------------------------------------------------------------------------+
Et lorsque Michael essaie de rechercher les privilèges de app_developer, il voit cette erreur :
MariaDB> SHOW GRANTS FOR FOR app_developer;
ERROR 1044 (42000): Access denied for user 'michael'@'localhost' to database 'mysql'
Cette astuce permet aux DBA d'afficher uniquement le groupement logique auquel appartient l'utilisateur et rien de plus. Nous pouvons réduire le vecteur d'attaque de cet aspect puisque les utilisateurs n'auront aucune idée des privilèges réels qui leur sont attribués.
Application du rôle par défaut dans MariaDB
En imposant un rôle par défaut, un utilisateur de base de données peut être protégé au premier niveau contre les erreurs humaines accidentelles. Par exemple, considérez l'utilisateur Michael qui a reçu le rôle app_developer, où le rôle app_developer est un sur-ensemble des rôles app_strucutre, app_writer et app_reader, comme illustré ci-dessous :
Puisque Michael appartient au rôle app_deleloper, nous pouvons également définir le privilège le plus bas comme rôle par défaut pour le protéger contre la modification accidentelle des données :
MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
Quant à l'utilisateur "michael", il verrait ce qui suit une fois connecté :
MariaDB> SELECT user(),current_role();
+-------------------+----------------+
| user() | current_role() |
+-------------------+----------------+
| [email protected] | app_reader |
+-------------------+----------------+
Son rôle par défaut est app_reader, qui est un privilège en lecture seule pour une base de données appelée "app". L'utilisateur actuel a la possibilité de basculer entre tous les rôles applicables à l'aide de la fonction SET ROLE. Quant à Michael, il peut passer à un autre rôle en utilisant l'instruction suivante :
MariaDB> SET ROLE app_developer;
À ce stade, Michael devrait pouvoir écrire dans la base de données « app », car app_developer est un sur-ensemble de app_writer et app_structure. Pour vérifier les rôles disponibles pour l'utilisateur actuel, nous pouvons interroger la table information_schema.applicable_roles :
MariaDB> SELECT * FROM information_schema.applicable_roles;
+-------------------+---------------+--------------+------------+
| GRANTEE | ROLE_NAME | IS_GRANTABLE | IS_DEFAULT |
+-------------------+---------------+--------------+------------+
| [email protected] | app_developer | NO | NO |
| app_developer | app_writer | NO | NULL |
| app_developer | app_reader | NO | NULL |
| app_developer | app_structure | NO | NULL |
| [email protected] | app_reader | NO | YES |
+-------------------+---------------+--------------+------------+
De cette façon, nous définissons en quelque sorte un rôle principal pour l'utilisateur, et le rôle principal peut être le privilège le plus bas possible pour un utilisateur spécifique. L'utilisateur doit consentir à son rôle actif, en passant à un autre rôle privilégié avant d'exécuter toute activité risquée sur le serveur de base de données.
Mappage des rôles dans MariaDB
MariaDB fournit une table de mappage de rôle appelée mysql.roles_mapping. Le mappage nous permet de comprendre facilement la corrélation entre un utilisateur et ses rôles, et comment un rôle est mappé à un autre rôle :
MariaDB> SELECT * FROM mysql.roles_mapping;
+-------------+-------------------+------------------+--------------+
| Host | User | Role | Admin_option |
+-------------+-------------------+------------------+--------------+
| localhost | root | app_developer | Y |
| localhost | root | app_writer | Y |
| localhost | root | app_reader | Y |
| localhost | root | app_structure | Y |
| | app_developer | app_structure | N |
| | app_developer | app_reader | N |
| | app_developer | app_writer | N |
| 192.168.0.% | michael | app_developer | N |
| localhost | michael | app_developer | N |
| localhost | root | mysqldump_backup | Y |
| localhost | dump_user1 | mysqldump_backup | N |
| localhost | root | mariadb_backup | Y |
| localhost | mariabackup_user1 | mariadb_backup | N |
+-------------+-------------------+------------------+--------------+
D'après la sortie ci-dessus, nous pouvons dire qu'un utilisateur sans hôte est essentiellement un rôle sur un rôle et que les utilisateurs administratifs (Admin_option =Y) sont également affectés automatiquement aux rôles créés. Pour obtenir la liste des rôles créés, nous pouvons interroger la table des utilisateurs MySQL :
MariaDB> SELECT user FROM mysql.user WHERE is_role = 'Y';
+------------------+
| User |
+------------------+
| app_developer |
| app_writer |
| app_reader |
| app_structure |
| mysqldump_backup |
| mariadb_backup |
+------------------+
Réflexions finales
L'utilisation de rôles peut améliorer la sécurité de la base de données en fournissant une couche supplémentaire de protection contre la modification accidentelle des données par les utilisateurs de la base de données. De plus, il simplifie la gestion des privilèges et les opérations de maintenance pour les organisations qui ont de nombreux utilisateurs de base de données.