MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Dicas e truques para implementar controles de acesso baseados em funções de banco de dados para MariaDB

Em um sistema de gerenciamento de banco de dados (DBMS), o controle de acesso baseado em função (RBAC), é uma restrição de recursos do banco de dados com base em um conjunto de grupos de privilégios predefinidos e se tornou um dos principais métodos para controle de acesso avançado. As funções de banco de dados podem ser criadas e descartadas, bem como ter privilégios concedidos e revogados. As funções podem ser concedidas e revogadas de contas de usuários individuais. As funções ativas aplicáveis ​​a uma conta podem ser selecionadas dentre aquelas concedidas à conta e alteradas durante as sessões dessa conta.

Nesta postagem de blog, abordaremos algumas dicas e truques sobre como usar a função de banco de dados para gerenciar privilégios de usuário e como um mecanismo avançado de controle de acesso para nosso acesso ao banco de dados. Se você quiser aprender sobre os conceitos básicos de funções no MySQL e no MariaDB, confira esta postagem do blog, Database User Management:Managing Roles for MariaDB.

Funções MySQL vs MariaDB

MySQL e MariaDB usam dois mecanismos de função diferentes. No MySQL 8.0 e posterior, a função é semelhante a outro usuário, com nome de usuário e host ('role1'@'localhost'). Sim, esse é o nome da função, que é praticamente semelhante à definição padrão de host de usuário. O MySQL armazena a definição de função da mesma forma que armazena privilégios de usuário na tabela de sistema mysql.user.

O MariaDB introduziu privilégios de função e acesso no MariaDB versão 10.0.5 (novembro de 2013), uns bons 8 anos antes do MySQL incluir esse recurso no MySQL8.0. Ele segue o gerenciamento de funções semelhante em um sistema de banco de dados compatível com SQL, mais robusto e muito mais fácil de entender. O MariaDB armazena a definição na tabela do sistema mysql.user sinalizada com uma coluna recém-adicionada chamada is_role. O MySQL armazena a função de forma diferente, usando uma combinação de usuário-host semelhante ao gerenciamento de usuários padrão do MySQL.

Tendo dito isso, a migração de funções entre esses dois DBMSs agora é incompatível entre si.

Funções administrativas e de backup do MariaDB

O MySQL possui privilégios dinâmicos, que fornecem um conjunto de privilégios para tarefas comuns de administração. Para MariaDB, podemos definir coisas semelhantes usando funções, especialmente para privilégios de backup e restauração. Para o MariaDB Backup, como é um backup físico e requer um conjunto diferente de privilégios, podemos criar uma função específica para que ele seja atribuído a outro usuário do banco de dados.

Primeiro, crie uma função e atribua a ela os privilégios corretos:

MariaDB> CREATE ROLE mariadb_backup;
MariaDB> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO mariadb_backup;

Podemos então criar o usuário de backup, conceder a ele a função mariadb_backup e atribuir a função padrão:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'passw0rdMMM';
MariaDB> GRANT mariadb_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mariadb_backup FOR [email protected];

Para mysqldump ou mariadb-dump, os privilégios mínimos para criar um backup podem ser definidos conforme abaixo:
MariaDB> CREATE ROLE mysqldump_backup;
MariaDB> GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON *.* TO mysqldump_backup;

Podemos então criar o usuário de backup, conceder-lhe a função mysqldump_backup e atribuir a função padrão:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_backup FOR [email protected];

Para restauração, geralmente requer um conjunto diferente de privilégios, que é um pouco:
MariaDB> CREATE ROLE mysqldump_restore;
MariaDB> GRANT SUPER, ALTER, INSERT, CREATE, DROP, LOCK TABLES, REFERENCES, SELECT, CREATE ROUTINE, TRIGGER ON *.* TO mysqldump_restore;

Podemos então criar o usuário de restauração, conceder a ele a função mysqldump_restore e atribuir a função padrão:
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_restore TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_restore FOR [email protected];

Usando esse truque, podemos simplificar o processo de criação de usuários administrativos, atribuindo uma função com privilégios pré-definidos. Assim, nossa declaração GRANT pode ser encurtada e fácil de entender.

Criando função sobre função no MariaDB 

Podemos criar outra função sobre uma função existente semelhante a uma associação de grupo aninhado com controle mais refinado sobre privilégios. Por exemplo, poderíamos criar as 4 funções a seguir:

MariaDB> CREATE ROLE app_developer, app_reader, app_writer, app_structure;

Conceda os privilégios para gerenciar a estrutura do esquema à função app_structure:

MariaDB> GRANT CREATE, ALTER, DROP, CREATE VIEW, CREATE ROUTINE, INDEX, TRIGGER, REFERENCES ON app.* to app_structure;

Conceda os privilégios para Data Manipulation Language (DML) à função app_writer:

MariaDB> GRANT INSERT, DELETE, UPDATE, CREATE TEMPORARY TABLES app.* to app_writer;

Conceda os privilégios de Data Query Language (DQL) à função app_reader:
MariaDB> GRANT SELECT, LOCK TABLES, SHOW VIEW app.* to app_reader;

E, finalmente, podemos atribuir todos os papéis acima ao app_developer, que deve ter controle total sobre o esquema:

MariaDB> GRANT app_structure TO app_developer;
MariaDB> GRANT app_reader TO app_developer;
MariaDB> GRANT app_writer TO app_developer;

As funções estão prontas e agora podemos criar um usuário de banco de dados com a função 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.%';

Como Michael agora pertence às funções app_deleloper e app_reader, também podemos atribuir os privilégios mais baixos como a função padrão para protegê-lo contra erros humanos indesejados:

MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';

O bom de usar uma função é que você pode ocultar os privilégios reais do usuário do banco de dados. Considere o seguinte usuário de banco de dados que acabou de fazer login:

MariaDB> SELECT user();
+----------------------+
| user()               |
+----------------------+
| [email protected] |
+----------------------+

Ao tentar recuperar os privilégios usando SHOW GRANTS, Michael veria:

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' |
+----------------------------------------------------------------------------------------------------------------+

E quando Michael estiver tentando procurar os privilégios do app_developer, ele verá este erro:

MariaDB> SHOW GRANTS FOR FOR app_developer;
ERROR 1044 (42000): Access denied for user 'michael'@'localhost' to database 'mysql'

Esse truque permite que os DBAs exibam apenas o agrupamento lógico ao qual o usuário pertence e nada mais. Podemos reduzir o vetor de ataque a partir desse aspecto, pois os usuários não terão ideia dos privilégios reais que estão sendo atribuídos a eles.

Aplicando a função padrão no MariaDB

Ao impor uma função padrão, um usuário de banco de dados pode ser protegido na primeira camada contra erros humanos acidentais. Por exemplo, considere o usuário Michael que recebeu a função app_developer, onde a função app_developer é um superconjunto de funções app_strucutre, app_writer e app_reader, conforme ilustrado abaixo:

Como Michael pertence à função app_deleloper, também podemos definir o privilégio mais baixo como a função padrão para protegê-lo contra modificação acidental de dados:

MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';

Quanto ao usuário "michael", ele veria o seguinte uma vez conectado:

MariaDB> SELECT user(),current_role();
+-------------------+----------------+
| user()            | current_role() |
+-------------------+----------------+
| [email protected] | app_reader     |
+-------------------+----------------+

Sua função padrão é app_reader, que é um privilégio somente leitura para um banco de dados chamado "app". O usuário atual tem a capacidade de alternar entre quaisquer funções aplicáveis ​​usando o recurso SET ROLE. Quanto a Michael, ele pode mudar para outra função usando a seguinte declaração:

MariaDB> SET ROLE app_developer;

Neste ponto, Michael deve ser capaz de gravar no banco de dados 'app', já que app_developer é um superconjunto de app_writer e app_structure. Para verificar as funções disponíveis para o usuário atual, podemos consultar a tabela 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        |
+-------------------+---------------+--------------+------------+

Dessa forma, estamos definindo uma função primária para o usuário, e a função primária pode ser o menor privilégio possível para um usuário específico. O usuário deve consentir sobre sua função ativa, alternando para outra função privilegiada antes de executar qualquer atividade arriscada no servidor de banco de dados.

Mapeamento de papéis no MariaDB

MariaDB fornece uma tabela de mapeamento de funções chamada mysql.roles_mapping. O mapeamento nos permite entender facilmente a correlação entre um usuário e suas funções e como uma função é mapeada para outra função:

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

A partir da saída acima, podemos dizer que um usuário sem um host é basicamente uma função sobre uma função e os usuários administrativos (Admin_option =Y) também estão sendo atribuídos às funções criadas automaticamente. Para obter a lista de funções criadas, podemos consultar a tabela de usuários do MySQL:

MariaDB> SELECT user FROM mysql.user WHERE is_role = 'Y';
+------------------+
| User             |
+------------------+
| app_developer    |
| app_writer       |
| app_reader       |
| app_structure    |
| mysqldump_backup |
| mariadb_backup   |
+------------------+

Considerações finais

O uso de funções pode melhorar a segurança do banco de dados fornecendo uma camada adicional de proteção contra modificação acidental de dados pelos usuários do banco de dados. Além disso, simplifica as operações de gerenciamento e manutenção de privilégios para organizações que possuem muitos usuários de banco de dados.