I et databasestyringssystem (DBMS) er rollebaseret adgangskontrol (RBAC) en begrænsning af databaseressourcer baseret på et sæt foruddefinerede grupper af privilegier og er blevet en af de vigtigste metoder til avanceret adgangskontrol. Databaseroller kan oprettes og slettes, samt få privilegier tildelt og tilbagekaldt fra dem. Roller kan tildeles og tilbagekaldes fra individuelle brugerkonti. De relevante aktive roller for en konto kan vælges blandt dem, der er tildelt kontoen og ændres under sessioner for den pågældende konto.
I dette blogindlæg vil vi dække nogle tips og tricks til at bruge databaserollen til at administrere brugerrettigheder og som en avanceret adgangskontrolmekanisme til vores databaseadgang. Hvis du gerne vil lære om det grundlæggende i roller i MySQL og MariaDB, så tjek dette blogindlæg, Database User Management:Managing Rolles for MariaDB.
MySQL vs MariaDB-roller
MySQL og MariaDB bruger to forskellige rollemekanismer. I MySQL 8.0 og nyere ligner rollen en anden bruger med brugernavn og vært ('role1'@'localhost'). Ja, det er rollenavnet, som praktisk talt svarer til standardbruger-værtsdefinitionen. MySQL gemmer rolledefinitionen ligesom ved lagring af brugerrettigheder i mysql.user systemtabellen.
MariaDB havde introduceret rolle- og adgangsrettigheder i MariaDB version 10.0.5 (november 2013), godt 8 år før MySQL inkluderede denne funktion i MySQL8.0. Den følger lignende rollestyring i et SQL-kompatibelt databasesystem, mere robust og meget lettere at forstå. MariaDB gemmer definitionen i mysql.user systemtabellen markeret med en nyligt tilføjet kolonne kaldet is_role. MySQL gemmer rollen anderledes ved at bruge en bruger-vært-kombination svarende til den almindelige MySQL-brugeradministration.
Når det er sagt, er rollemigrering mellem disse to DBMS'er nu inkompatibel med hinanden.
MariaDB administrator- og sikkerhedskopieringsroller
MySQL har dynamiske privilegier, som giver et sæt privilegier til almindelige administrationsopgaver. For MariaDB kan vi indstille lignende ting ved hjælp af roller, især til sikkerhedskopiering og gendannelsesprivilegier. For MariaDB Backup, da det er en fysisk sikkerhedskopi og kræver et andet sæt privilegier, kan vi oprette en specifik rolle, som den skal tildeles til en anden databasebruger.
Opret først en rolle og tildel den med de rigtige rettigheder:
MariaDB> CREATE ROLE mariadb_backup;
MariaDB> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO mariadb_backup;
Vi kan derefter oprette backup-brugeren, tildele den mariadb_backup-rollen og tildele standardrollen:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'passw0rdMMM';
MariaDB> GRANT mariadb_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mariadb_backup FOR [email protected];
For mysqldump eller mariadb-dump kan de minimale privilegier til at oprette en sikkerhedskopi indstilles som nedenfor:
MariaDB> CREATE ROLE mysqldump_backup;
MariaDB> GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON *.* TO mysqldump_backup;
Vi kan derefter oprette backup-brugeren, give den rollen mysqldump_backup og tildele standardrollen:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_backup FOR [email protected];
Til gendannelse kræver det almindeligvis et andet sæt privilegier, hvilket er lidt:
MariaDB> CREATE ROLE mysqldump_restore;
MariaDB> GRANT SUPER, ALTER, INSERT, CREATE, DROP, LOCK TABLES, REFERENCES, SELECT, CREATE ROUTINE, TRIGGER ON *.* TO mysqldump_restore;
Vi kan derefter oprette gendannelsesbrugeren, tildele den rollen mysqldump_restore og tildele standardrollen:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_restore TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_restore FOR [email protected];
Ved at bruge dette trick kan vi forenkle den administrative brugeroprettelsesprocessen ved at tildele en rolle med foruddefinerede privilegier. Således kan vores GRANT-opgørelse forkortes og let at forstå.
Oprettelse af rolle over rolle i MariaDB
Vi kan oprette en anden rolle over en eksisterende rolle, der ligner et indlejret gruppemedlemskab med mere finmasket kontrol over privilegier. For eksempel kunne vi oprette følgende 4 roller:
MariaDB> CREATE ROLE app_developer, app_reader, app_writer, app_structure;
Giv rettighederne til at administrere skemastrukturen til rollen app_structure:
MariaDB> GRANT CREATE, ALTER, DROP, CREATE VIEW, CREATE ROUTINE, INDEX, TRIGGER, REFERENCES ON app.* to app_structure;
Tildel privilegierne for Data Manipulation Language (DML) til rollen app_writer:
MariaDB> GRANT INSERT, DELETE, UPDATE, CREATE TEMPORARY TABLES app.* to app_writer;
Giv rettighederne til Data Query Language (DQL) til rollen app_reader:
MariaDB> GRANT SELECT, LOCK TABLES, SHOW VIEW app.* to app_reader;
Og endelig kan vi tildele alle ovenstående roller til app_developer, som skal have fuld kontrol over skemaet:
MariaDB> GRANT app_structure TO app_developer;
MariaDB> GRANT app_reader TO app_developer;
MariaDB> GRANT app_writer TO app_developer;
Rollerne er klar, og nu kan vi oprette en databasebruger med rollen 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.%';
Da Michael nu tilhører rollerne app_deleloper og app_reader, kan vi også tildele de laveste privilegier som standardrolle for at beskytte ham mod uønskede menneskelige fejl:
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
Det gode ved at bruge en rolle er, at du kan skjule de faktiske privilegier for databasebrugeren. Overvej følgende databasebruger, der lige er logget ind:
MariaDB> SELECT user();
+----------------------+
| user() |
+----------------------+
| [email protected] |
+----------------------+
Når han forsøgte at hente rettighederne ved hjælp af SHOW GRANTS, ville Michael se:
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' |
+----------------------------------------------------------------------------------------------------------------+
Og når Michael forsøger at finde app_developer's privilegier, vil han se denne fejl:
MariaDB> SHOW GRANTS FOR FOR app_developer;
ERROR 1044 (42000): Access denied for user 'michael'@'localhost' to database 'mysql'
Dette trick tillader DBA'erne kun at vise den logiske gruppering, hvor brugeren hører til, og intet mere. Vi kan reducere angrebsvektoren fra dette aspekt, da brugerne ikke har nogen idé om de faktiske privilegier, der er tildelt dem.
Håndhævelse af standardrolle i MariaDB
Ved at håndhæve en standardrolle kan en databasebruger beskyttes på det første lag mod utilsigtede menneskelige fejl. Overvej f.eks. brugeren Michael, som har fået rollen app_developer, hvor app_developer-rollen er et supersæt af app_strucutre-, app_writer- og app_reader-roller, som illustreret nedenfor:
Da Michael tilhører rollen app_deleloper, kan vi også indstille det laveste privilegium som standardrolle for at beskytte ham mod utilsigtet dataændring:
MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
Med hensyn til brugeren "michael", vil han se følgende, når han er logget ind:
MariaDB> SELECT user(),current_role();
+-------------------+----------------+
| user() | current_role() |
+-------------------+----------------+
| [email protected] | app_reader |
+-------------------+----------------+
Dens standardrolle er app_reader, som er et skrivebeskyttet privilegium for en database kaldet "app". Den aktuelle bruger har mulighed for at skifte mellem alle relevante roller ved hjælp af funktionen SET ROLLE. Hvad angår Michael, kan han skifte til en anden rolle ved at bruge følgende udsagn:
MariaDB> SET ROLE app_developer;
På dette tidspunkt burde Michael være i stand til at skrive til databasen 'app', da app_developer er et supersæt af app_writer og app_structure. For at kontrollere de tilgængelige roller for den aktuelle bruger kan vi forespørge tabellen 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 |
+-------------------+---------------+--------------+------------+
På denne måde indstiller vi en primær rolle for brugeren, og den primære rolle kan være det lavest mulige privilegium for en bestemt bruger. Brugeren skal give samtykke til sin aktive rolle ved at skifte til en anden privilegeret rolle, før han udfører nogen risikofyldt aktivitet på databaseserveren.
Rollemapping i MariaDB
MariaDB leverer en rolletilknytningstabel kaldet mysql.roles_mapping. Kortlægningen giver os mulighed for nemt at forstå sammenhængen mellem en bruger og dens roller, og hvordan en rolle er knyttet til en anden rolle:
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 |
+-------------+-------------------+------------------+--------------+
Fra ovenstående output kan vi se, at en bruger uden en vært dybest set er en rolle i forhold til en rolle, og administrative brugere (Admin_option =Y) bliver også automatisk tildelt de oprettede roller. For at få listen over oprettede roller kan vi forespørge i MySQL-brugertabellen:
MariaDB> SELECT user FROM mysql.user WHERE is_role = 'Y';
+------------------+
| User |
+------------------+
| app_developer |
| app_writer |
| app_reader |
| app_structure |
| mysqldump_backup |
| mariadb_backup |
+------------------+
Sidste tanker
Brug af roller kan forbedre databasesikkerheden ved at give et ekstra lag af beskyttelse mod utilsigtet dataændring fra databasebrugerne. Ydermere forenkler det privilegieadministration og vedligeholdelsesoperationer for organisationer, der har mange databasebrugere.