SYSTEM_USERとは
SYSTEM_USERはMySQL8.0.16で追加された権限です。この権限を付与されているユーザーはシステムユーザーとして扱われます。
本記事ではこの機能を使用して重要なアカウントをシステムユーザーに設定して、他のユーザーによって不正に権限を変更されたり、意図せずユーザーを削除されてしまわないように保護する方法を紹介します。
システムユーザー
システムユーザーはMySQL8.0.16以降の概念です。
ユーザーはSYSTEM_USER権限の有無でシステムユーザーとレギュラーユーザーの二つのカテゴリに分けられます。
システムユーザーはレギュラーユーザーからDROP USERやREVOKEなどのコマンドによるアカウントの操作を受け付けなくなります。
アカウント操作は以下の操作を指します。
- アカウントの作成と削除
- 権限の付与と取り消し
- 資格情報や認証プラグインなどのアカウント認証特性の変更
- パスワードの有効期限ポリシー
など
システムユーザーとレギュラーユーザーのアカウント操作の可否は以下の図のようになります。
上の図では
- システムユーザーAとBはSYSTEM_USER権限を持っています。
- システムユーザーAとレギュラーユーザーAはCREATE USERなどアカウント操作に関する必要な権限を持っているとします。
このとき、
- ユーザーAは同じカテゴリのユーザーBに対してアカウント操作を行うことができます
- システムユーザーAはレギュラーユーザーBに対してもアカウント操作を行うことができます。
しかし、
- レギュラーユーザーAはシステムユーザーBに対してアカウント操作を行う事ができません。
重要なアカウントを保護する
こちらのマニュアルを参考にSYSTEM_USER機能を使用してアカウントを他のユーザーから変更されないように設定してみましょう。
アカウントを操作する方法は次の2つです。
- CREATE USER, ALTER USER, DROP USER, GRANT, REVOKEコマンドなどを使用する
- mysqlスキーマのテーブルを直接操作する
重要なアカウントに対してSYSTEM_USER権限を付与することで、他のユーザー(レギュラーユーザー)からREVOKEコマンドなどでアカウントを操作されることを防ぎます。
1 |
mysql> GRANT SYSTEM_USER ON *.* TO userA; |
また、他のユーザー(レギュラーユーザー)にmysqlスキーマへのUPDATEやDELETEなどの権限を与えないことで、テーブルを直接操作してアカウント操作を行うことを防ぎます。
※ユーザーに対してグローバルに権限を付与している場合は、partial revoke機能を使用することで、mysql.* など特定のスキーマのみ権限をはく奪することが容易となります。
1 |
mysql> REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM userB; |
partial revoke機能は以前こちらの記事で紹介しています。
検証
実際にシステムユーザーに設定するとレギュラーユーザーからアカウント操作をされないことを確認してみます。
ユーザーを4つ作成します。
1 2 3 4 |
mysql> CREATE USER system_userA IDENTIFIED BY 'MySQL8.0'; mysql> CREATE USER system_userB IDENTIFIED BY 'MySQL8.0'; mysql> CREATE USER regular_userA IDENTIFIED BY 'MySQL8.0'; mysql> CREATE USER regular_userB IDENTIFIED BY 'MySQL8.0'; |
system_userAとsystem_userBにSYSTEM_USER権限を付与してシステムユーザーにします。
また、全てのユーザーにSELECT権限とGRANT OPTIONを付与しておきます。
1 2 3 4 |
mysql> GRANT SELECT,SYSTEM_USER ON *.* TO system_userA WITH GRANT OPTION; mysql> GRANT SELECT,SYSTEM_USER ON *.* TO system_userB WITH GRANT OPTION; mysql> GRANT SELECT ON *.* TO regular_userA WITH GRANT OPTION; mysql> GRANT SELECT ON *.* TO regular_userB WITH GRANT OPTION; |
system_userAとregular_userAでそれぞれ接続して、system_userBと regular_userBに対してアカウント操作を試してみます。
今回はSELECT権限をREVOKEしてみます。
システムユーザAによるアカウント操作
システムユーザーAでログインします。
1 |
$ mysql -u system_userA -p |
システムユーザーBに対してもレギュラーユーザーBに対してもアカウント操作はできます。
1 2 3 4 5 |
mysql> REVOKE SELECT ON *.* FROM regular_userB; Query OK, 0 rows affected (0.01 sec) mysql> REVOKE SELECT ON *.* FROM system_userB; Query OK, 0 rows affected (0.01 sec) |
レギュラーユーザAによるアカウント操作
レギュラーユーザーAでログインします。
1 |
$ mysql -u regular_userA -p |
レギュラーユーザーBに対してアカウント操作はできます。一方、システムユーザーBにはアカウント操作できないことが確認できます。
1 2 3 4 5 |
mysql> REVOKE SELECT ON *.* FROM regular_userB; Query OK, 0 rows affected (0.01 sec) mysql> REVOKE SELECT ON *.* FROM system_userB; ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation |
まとめ
CREATE USERに必要なCREATE USER権限はユーザー作成だけではなくALTER USERやDROP USERなどユーザーの変更や削除も同時に許可してしまう強力な権限です。
root以外のユーザーでユーザー作成などを行っている場合は、SYSTEM_USER権限をうまく使いこなすことで、CREATE USER権限などの付与と、rootなどの重要なアカウントへの変更操作のブロックを両立させることができます。
MySQL8.0にはセキュリティ強化のためアカウント管理に関する機能が多く追加されています。今後も気になる機能はblogで紹介していきます。