W systemie zarządzania bazami danych (DBMS) kontrola dostępu oparta na rolach (RBAC) jest ograniczeniem zasobów bazy danych w oparciu o zestaw predefiniowanych grup uprawnień i stała się jednym z głównych metody zaawansowanej kontroli dostępu. Role bazy danych można tworzyć i usuwać, a także nadawać i odbierać im uprawnienia. Role mogą być przyznawane i odwoływane z indywidualnych kont użytkowników. Odpowiednie aktywne role dla konta można wybrać spośród tych przyznanych kontu i zmieniać podczas sesji dla tego konta.
W tym poście na blogu omówimy kilka porad i wskazówek dotyczących używania roli bazy danych do zarządzania uprawnieniami użytkowników oraz jako zaawansowanego mechanizmu kontroli dostępu do naszej bazy danych. Jeśli chcesz poznać podstawy ról w MySQL i MariaDB, zapoznaj się z tym wpisem na blogu Zarządzanie użytkownikami bazy danych:Zarządzanie rolami w MariaDB.
Role MySQL i MariaDB
MySQL i MariaDB używają dwóch różnych mechanizmów ról. W MySQL 8.0 i nowszych rola jest podobna do innego użytkownika, z nazwą użytkownika i hostem ('role1'@'localhost'). Tak, to jest nazwa roli, która jest praktycznie podobna do standardowej definicji hosta użytkownika. MySQL przechowuje definicję roli, tak jak przechowuje uprawnienia użytkownika w tabeli systemowej mysql.user.
MariaDB wprowadziła role i uprawnienia dostępu w MariaDB w wersji 10.0.5 (listopad 2013), dobre 8 lat przed włączeniem tej funkcji przez MySQL do MySQL8.0. Podąża za podobnym zarządzaniem rolami w systemie baz danych zgodnym z SQL, bardziej niezawodnym i znacznie łatwiejszym do zrozumienia. MariaDB przechowuje definicję w tabeli systemowej mysql.user oflagowaną nowo dodaną kolumną o nazwie is_role. MySQL przechowuje rolę w inny sposób, używając kombinacji użytkownik-host podobnej do standardowego zarządzania użytkownikami MySQL.
Mówiąc to, migracja ról między tymi dwoma DBMS jest teraz niekompatybilna ze sobą.
Role administracyjne i zapasowe MariaDB
MySQL ma dynamiczne uprawnienia, które zapewniają zestaw uprawnień do typowych zadań administracyjnych. W przypadku MariaDB możemy ustawić podobne rzeczy za pomocą ról, zwłaszcza w przypadku uprawnień do tworzenia kopii zapasowych i przywracania. W przypadku MariaDB Backup, ponieważ jest to fizyczna kopia zapasowa i wymaga innego zestawu uprawnień, możemy utworzyć określoną rolę, aby przypisać ją innemu użytkownikowi bazy danych.
Najpierw utwórz rolę i przypisz ją z odpowiednimi uprawnieniami:
MariaDB> CREATE ROLE mariadb_backup;
MariaDB> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO mariadb_backup;
Następnie możemy utworzyć użytkownika kopii zapasowej, nadać mu rolę mariadb_backup i przypisać rolę domyślną:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'passw0rdMMM';
MariaDB> GRANT mariadb_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mariadb_backup FOR [email protected];
W przypadku mysqldump lub mariadb-dump minimalne uprawnienia do tworzenia kopii zapasowej można ustawić w następujący sposób:
MariaDB> CREATE ROLE mysqldump_backup;
MariaDB> GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON *.* TO mysqldump_backup;
Następnie możemy utworzyć użytkownika kopii zapasowej, nadać mu rolę mysqldump_backup i przypisać rolę domyślną:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_backup FOR [email protected];
Do przywrócenia zwykle wymaga innego zestawu uprawnień, czyli trochę:
MariaDB> CREATE ROLE mysqldump_restore;
MariaDB> GRANT SUPER, ALTER, INSERT, CREATE, DROP, LOCK TABLES, REFERENCES, SELECT, CREATE ROUTINE, TRIGGER ON *.* TO mysqldump_restore;
Następnie możemy utworzyć użytkownika przywracającego, nadać mu rolę mysqldump_restore i przypisać rolę domyślną:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_restore TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_restore FOR [email protected];
Korzystając z tej sztuczki, możemy uprościć proces tworzenia użytkownika administracyjnego, przypisując rolę ze wstępnie zdefiniowanymi uprawnieniami. W ten sposób nasze oświadczenie GRANT może być skrócone i łatwe do zrozumienia.
Tworzenie roli nad rolą w MariaDB
Możemy utworzyć inną rolę na istniejącej roli, podobnie jak członkostwo w grupie zagnieżdżonej, z bardziej precyzyjną kontrolą nad uprawnieniami. Na przykład możemy utworzyć następujące 4 role:
MariaDB> CREATE ROLE app_developer, app_reader, app_writer, app_structure;
Przyznaj uprawnienia do zarządzania strukturą schematu roli app_structure:
MariaDB> GRANT CREATE, ALTER, DROP, CREATE VIEW, CREATE ROUTINE, INDEX, TRIGGER, REFERENCES ON app.* to app_structure;
Przyznaj uprawnienia do języka manipulacji danymi (DML) roli app_writer:
MariaDB> GRANT INSERT, DELETE, UPDATE, CREATE TEMPORARY TABLES app.* to app_writer;
Przyznaj uprawnienia do języka zapytań danych (DQL) roli app_reader:
MariaDB> GRANT SELECT, LOCK TABLES, SHOW VIEW app.* to app_reader;
I na koniec możemy przypisać wszystkie powyższe role do app_developer, który powinien mieć pełną kontrolę nad schematem:
MariaDB> GRANT app_structure TO app_developer;
MariaDB> GRANT app_reader TO app_developer;
MariaDB> GRANT app_writer TO app_developer;
Role są gotowe i teraz możemy utworzyć użytkownika bazy danych z rolą 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.%';
Ponieważ Michael należy teraz do ról app_deleloper i app_reader, możemy również przypisać najniższe uprawnienia jako rolę domyślną, aby chronić go przed niepożądanym ludzkim błędem:
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
Dobrą rzeczą w używaniu roli jest to, że możesz ukryć rzeczywiste uprawnienia przed użytkownikiem bazy danych. Weź pod uwagę następującego użytkownika bazy danych, który właśnie się zalogował:
MariaDB> SELECT user();
+----------------------+
| user() |
+----------------------+
| [email protected] |
+----------------------+
Podczas próby odzyskania uprawnień za pomocą POKAŻ DOTACJE Michael zobaczył:
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' |
+----------------------------------------------------------------------------------------------------------------+
A kiedy Michael próbuje sprawdzić uprawnienia app_developer, zobaczy ten błąd:
MariaDB> SHOW GRANTS FOR FOR app_developer;
ERROR 1044 (42000): Access denied for user 'michael'@'localhost' to database 'mysql'
Ta sztuczka pozwala administratorom baz danych na pokazanie tylko logicznego grupowania, do którego należy użytkownik i nic więcej. Możemy zredukować wektor ataku z tego aspektu, ponieważ użytkownicy nie będą mieli pojęcia, jakie uprawnienia zostały im przypisane.
Wymuszanie domyślnej roli w MariaDB
Wymuszając domyślną rolę, użytkownik bazy danych może być chroniony na pierwszej warstwie przed przypadkowymi błędami ludzkimi. Rozważmy na przykład użytkownika Michael, któremu przyznano rolę app_developer, gdzie rola app_developer jest nadzbiorem ról app_strucutre, app_writer i app_reader, jak pokazano poniżej:
Ponieważ Michael należy do roli app_deleloper, możemy również ustawić najniższe uprawnienia jako domyślną rolę chroniącą go przed przypadkową modyfikacją danych:
MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
Jeśli chodzi o użytkownika „michael”, po zalogowaniu zobaczyłby on:
MariaDB> SELECT user(),current_role();
+-------------------+----------------+
| user() | current_role() |
+-------------------+----------------+
| [email protected] | app_reader |
+-------------------+----------------+
Jego domyślną rolą jest app_reader, co jest uprawnieniem tylko do odczytu bazy danych o nazwie „app”. Bieżący użytkownik ma możliwość przełączania się między dowolnymi odpowiednimi rolami za pomocą funkcji SET ROLE. Jeśli chodzi o Michaela, może on przejść do innej roli, używając następującego oświadczenia:
MariaDB> SET ROLE app_developer;
W tym momencie Michael powinien być w stanie pisać do bazy danych „app”, ponieważ app_developer jest nadzbiorem app_writer i app_structure. Aby sprawdzić dostępne role dla bieżącego użytkownika, możemy wysłać zapytanie do tabeli 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 |
+-------------------+---------------+--------------+------------+
W ten sposób ustalamy podstawową rolę dla użytkownika, a rola podstawowa może być najniższym możliwym przywilejem dla konkretnego użytkownika. Użytkownik musi wyrazić zgodę na swoją aktywną rolę, przełączając się do innej uprzywilejowanej roli przed wykonaniem jakiejkolwiek ryzykownej aktywności na serwerze bazy danych.
Mapowanie ról w MariaDB
MariaDB udostępnia tabelę mapowania ról o nazwie mysql.roles_mapping. Mapowanie pozwala nam łatwo zrozumieć korelację między użytkownikiem a jego rolami oraz sposób mapowania roli na inną rolę:
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 |
+-------------+-------------------+------------------+--------------+
Z powyższych danych wyjściowych możemy stwierdzić, że użytkownik bez hosta jest zasadniczo rolą nad rolą, a użytkownicy administracyjni (Admin_option =Y) są również automatycznie przypisywani do utworzonych ról. Aby uzyskać listę utworzonych ról, możemy wysłać zapytanie do tabeli użytkowników MySQL:
MariaDB> SELECT user FROM mysql.user WHERE is_role = 'Y';
+------------------+
| User |
+------------------+
| app_developer |
| app_writer |
| app_reader |
| app_structure |
| mysqldump_backup |
| mariadb_backup |
+------------------+
Ostateczne myśli
Korzystanie z ról może poprawić bezpieczeństwo bazy danych, zapewniając dodatkową warstwę ochrony przed przypadkową modyfikacją danych przez użytkowników bazy danych. Ponadto upraszcza zarządzanie uprawnieniami i operacje konserwacyjne dla organizacji, które mają wielu użytkowników baz danych.