データベース管理システム(DBMS)では、役割ベースのアクセス制御(RBAC)は、事前定義された一連の特権グループに基づくデータベースリソースの制限であり、主要なものの1つになっています。高度なアクセス制御の方法。データベースの役割は、作成および削除したり、権限を付与したり取り消したりすることができます。個々のユーザーアカウントにロールを付与したり、アカウントから取り消すことができます。アカウントに適用可能なアクティブな役割は、アカウントに付与された役割から選択し、そのアカウントのセッション中に変更できます。
このブログ投稿では、データベースの役割を使用してユーザー権限を管理し、データベースアクセスの高度なアクセス制御メカニズムとして使用するためのヒントとコツについて説明します。 MySQLとMariaDBのロールの基本について知りたい場合は、このブログ投稿「データベースユーザー管理:MariaDBのロールの管理」を確認してください。
MySQLとMariaDBの役割
MySQLとMariaDBは、2つの異なるロールメカニズムを使用します。 MySQL 8.0以降では、ロールは別のユーザーに似ていますが、ユーザー名とホスト('role1' @'localhost')があります。はい、それはロール名であり、標準のユーザーホスト定義と実質的に同じです。 MySQLは、mysql.userシステムテーブルにユーザー権限を保存するのと同じようにロール定義を保存します。
MariaDBは、MariaDBバージョン10.0.5(2013年11月)に役割とアクセス権限を導入しました。これは、MySQLがMySQL8.0にこの機能を含める8年前のことです。これは、SQL準拠のデータベースシステムでの同様の役割管理に従い、より堅牢で、はるかに理解しやすくなっています。 MariaDBは、is_roleという新しく追加された列でフラグが付けられたmysql.userシステムテーブルに定義を格納します。 MySQLは、標準のMySQLユーザー管理と同様のユーザーとホストの組み合わせを使用して、役割を異なる方法で保存します。
そうは言っても、これら2つのDBMS間の役割の移行は相互に互換性がなくなりました。
MariaDBの管理およびバックアップの役割
MySQLには動的特権があり、一般的な管理タスクに一連の特権を提供します。 MariaDBの場合、特にバックアップと復元の特権について、ロールを使用して同様の設定を行うことができます。 MariaDBバックアップの場合、これは物理バックアップであり、異なる特権のセットが必要なため、別のデータベースユーザーに割り当てるための特定のロールを作成できます。
まず、役割を作成し、適切な権限を割り当てます。
MariaDB> CREATE ROLE mariadb_backup;
MariaDB> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO mariadb_backup;
次に、バックアップユーザーを作成し、mariadb_backupロールを付与して、デフォルトのロールを割り当てることができます。
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'passw0rdMMM';
MariaDB> GRANT mariadb_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mariadb_backup FOR [email protected];
mysqldumpまたはmariadb-dumpの場合、バックアップを作成するための最小限の権限は次のように設定できます。
MariaDB> CREATE ROLE mysqldump_backup;
MariaDB> GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON *.* TO mysqldump_backup;
次に、バックアップユーザーを作成し、mysqldump_backupロールを付与して、デフォルトのロールを割り当てることができます。
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_backup TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_backup FOR [email protected];
復元するには、通常、別の特権のセットが必要ですが、これは少しです:
MariaDB> CREATE ROLE mysqldump_restore;
MariaDB> GRANT SUPER, ALTER, INSERT, CREATE, DROP, LOCK TABLES, REFERENCES, SELECT, CREATE ROUTINE, TRIGGER ON *.* TO mysqldump_restore;
次に、復元ユーザーを作成し、mysqldump_restoreロールを付与して、デフォルトのロールを割り当てることができます。
MariaDB> CREATE USER [email protected] IDENTIFIED BY 'p4ss182MMM';
MariaDB> GRANT mysqldump_restore TO [email protected];
MariaDB> SET DEFAULT ROLE mysqldump_restore FOR [email protected];
このトリックを使用することで、事前定義された特権を持つロールを割り当てることにより、管理ユーザーの作成プロセスを簡素化できます。したがって、GRANTステートメントを短くして理解しやすくすることができます。
MariaDBでの役割よりも役割の作成
ネストされたグループメンバーシップと同様に、既存の役割に対して別の役割を作成して、特権をよりきめ細かく制御できます。たとえば、次の4つの役割を作成できます。
MariaDB> CREATE ROLE app_developer, app_reader, app_writer, app_structure;
MariaDB> GRANT CREATE, ALTER, DROP, CREATE VIEW, CREATE ROUTINE, INDEX, TRIGGER, REFERENCES ON app.* to app_structure;
データ操作言語(DML)の権限をapp_writerロールに付与します:
MariaDB> GRANT INSERT, DELETE, UPDATE, CREATE TEMPORARY TABLES app.* to app_writer;
app_readerロールにデータクエリ言語(DQL)の権限を付与します:
MariaDB> GRANT SELECT, LOCK TABLES, SHOW VIEW app.* to app_reader;
最後に、上記のすべての役割をapp_developerに割り当てることができます。app_developerはスキーマを完全に制御する必要があります。
MariaDB> GRANT app_structure TO app_developer;
MariaDB> GRANT app_reader TO app_developer;
MariaDB> GRANT app_writer TO app_developer;
ロールの準備が整いました。これで、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.%';
Michaelはapp_deleloperとapp_readerの役割に属しているため、デフォルトの役割として最低の権限を割り当てて、不要な人為的ミスから彼を保護することもできます。
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
ロールを使用することの良い点は、データベースユーザーから実際の特権を隠すことができることです。ログインしたばかりの次のデータベースユーザーについて考えてみます。
MariaDB> SELECT user();
+----------------------+
| user() |
+----------------------+
| [email protected] |
+----------------------+
SHOW GRANTSを使用して特権を取得しようとすると、Michaelは次のように表示されます。
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' |
+----------------------------------------------------------------------------------------------------------------+
そして、Michaelがapp_developerの特権を検索しようとすると、次のエラーが表示されます:
MariaDB> SHOW GRANTS FOR FOR app_developer;
ERROR 1044 (42000): Access denied for user 'michael'@'localhost' to database 'mysql'
このトリックにより、DBAは、ユーザーが属する論理グループのみを表示し、それ以上は表示できません。ユーザーは実際に割り当てられている特権を知らないため、この側面から攻撃ベクトルを減らすことができます。
MariaDBでデフォルトの役割を強制する
デフォルトの役割を適用することにより、データベースユーザーを最初のレイヤーで偶発的な人為的ミスから保護できます。たとえば、app_developerロールが付与されているユーザーMichaelについて考えてみます。ここで、app_developerロールは、以下に示すように、app_strucutre、app_writer、およびapp_readerロールのスーパーセットです。
Michaelはapp_deleloperロールに属しているため、最低の権限を設定することもできます偶発的なデータ変更から彼を保護するためのデフォルトの役割として:
MariaDB> GRANT app_reader TO 'michael'@'192.168.0.%';
MariaDB> SET DEFAULT ROLE app_reader FOR 'michael'@'192.168.0.%';
ユーザー「michael」については、ログインすると次のように表示されます。
MariaDB> SELECT user(),current_role();
+-------------------+----------------+
| user() | current_role() |
+-------------------+----------------+
| [email protected] | app_reader |
+-------------------+----------------+
デフォルトの役割はapp_readerです。これは、「app」と呼ばれるデータベースのread_only特権です。現在のユーザーは、SET ROLE機能を使用して、該当するロールを切り替えることができます。マイケルについては、次のステートメントを使用して別の役割に切り替えることができます。
MariaDB> SET ROLE app_developer;
この時点で、app_developerはapp_writerとapp_structureのスーパーセットであるため、Michaelはデータベース'app'に書き込むことができるはずです。現在のユーザーが使用できるロールを確認するには、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 |
+-------------------+---------------+--------------+------------+
このように、ユーザーのプライマリロールを設定します。プライマリロールは、特定のユーザーに対して可能な限り低い特権にすることができます。ユーザーは、データベースサーバーに対して危険なアクティビティを実行する前に、別の特権ロールに切り替えることにより、アクティブなロールについて同意する必要があります。
MariaDBでのロールマッピング
MariaDBは、mysql.roles_mappingと呼ばれるロールマッピングテーブルを提供します。マッピングにより、ユーザーとその役割の相関関係、および役割が別の役割にどのようにマッピングされるかを簡単に理解できます。
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 |
+-------------+-------------------+------------------+--------------+
上記の出力から、ホストのないユーザーは基本的にロールに対するロールであり、管理ユーザー(Admin_option =Y)も作成されたロールに自動的に割り当てられていることがわかります。作成されたロールのリストを取得するには、MySQLユーザーテーブルをクエリします。
MariaDB> SELECT user FROM mysql.user WHERE is_role = 'Y';
+------------------+
| User |
+------------------+
| app_developer |
| app_writer |
| app_reader |
| app_structure |
| mysqldump_backup |
| mariadb_backup |
+------------------+
ロールを使用すると、データベースユーザーによる偶発的なデータ変更に対する保護の追加レイヤーを提供することにより、データベースのセキュリティを向上させることができます。さらに、データベースユーザーが多い組織の特権管理と保守操作が簡素化されます。