権限管理
TiDB は、構文や権限タイプを含むMySQL 5.7の権限管理システムをサポートしています。 MySQL 8.0 の次の機能もサポートされています。
- TiDB 3.0 以降の SQL ロール。
- TiDB 5.1 以降の動的権限。
このドキュメントでは、権限関連の TiDB 操作、TiDB 操作に必要な権限、および権限システムの実装について紹介します。
権限関連の操作
権限を付与する
GRANT
ステートメントは、ユーザー アカウントに権限を付与します。
たとえば、次のステートメントを使用して、 xxx
人のユーザーにtest
データベースを読み取る権限を付与します。
GRANT SELECT ON test.* TO 'xxx'@'%';
次のステートメントを使用して、 xxx
のユーザーにすべてのデータベースに対するすべての権限を付与します。
GRANT ALL PRIVILEGES ON *.* TO 'xxx'@'%';
デフォルトでは、指定したユーザーが存在しない場合、 GRANT
ステートメントはエラーを返します。この動作は、SQL モードNO_AUTO_CREATE_USER
が指定されているかどうかによって異なります。
mysql> SET sql_mode=DEFAULT;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON test.* TO 'idontexist';
ERROR 1105 (HY000): You are not allowed to create a user with GRANT
mysql> SELECT user,host,authentication_string FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
次の例では、SQL モードNO_AUTO_CREATE_USER
が設定されていないため、ユーザーidontexist
は空のパスワードで自動的に作成されます。これはセキュリティ上のリスクがあるためお勧めできません。ユーザー名のスペルを間違えると、空のパスワードで新しいユーザーが作成されます。
mysql> SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON test.* TO 'idontexist';
Query OK, 1 row affected (0.05 sec)
mysql> SELECT user,host,authentication_string FROM mysql.user WHERE user='idontexist';
+------------+------+-----------------------+
| user | host | authentication_string |
+------------+------+-----------------------+
| idontexist | % | |
+------------+------+-----------------------+
1 row in set (0.01 sec)
GRANT
ではあいまい一致を使用して、データベースに権限を付与できます。
mysql> GRANT ALL PRIVILEGES ON `te%`.* TO genius;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT user,host,db FROM mysql.db WHERE user='genius';
+--------|------|-----+
| user | host | db |
+--------|------|-----+
| genius | % | te% |
+--------|------|-----+
1 row in set (0.00 sec)
この例では、 %
in te%
のため、 te
で始まるすべてのデータベースに権限が付与されます。
権限を取り消す
REVOKE
ステートメントにより、システム管理者はユーザー アカウントから権限を取り消すことができます。
REVOKE
ステートメントはREVOKE
ステートメントに対応します。
REVOKE ALL PRIVILEGES ON `test`.* FROM 'genius'@'localhost';
ノート:
権限を取り消すには、完全に一致する必要があります。一致する結果が見つからない場合は、エラーが表示されます。
mysql> REVOKE ALL PRIVILEGES ON `te%`.* FROM 'genius'@'%';
ERROR 1141 (42000): There is no such grant defined for user 'genius' on host '%'
あいまい一致、エスケープ、文字列、識別子について:
mysql> GRANT ALL PRIVILEGES ON `te\%`.* TO 'genius'@'localhost';
Query OK, 0 rows affected (0.00 sec)
この例では、完全一致を使用してte%
という名前のデータベースを検索します。 %
\
エスケープ文字が使用されているため、 %
はワイルドカードとはみなされないことに注意してください。
文字列は一重引用符 ('') で囲まれ、識別子はバッククォート (``) で囲まれます。以下の違いを参照してください。
mysql> GRANT ALL PRIVILEGES ON 'test'.* TO 'genius'@'localhost';
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near ''test'.* to 'genius'@'localhost'' at line 1
mysql> GRANT ALL PRIVILEGES ON `test`.* TO 'genius'@'localhost';
Query OK, 0 rows affected (0.00 sec)
特別なキーワードをテーブル名として使用する場合は、キーワードをバッククォート (``) で囲みます。例えば:
mysql> CREATE TABLE `select` (id int);
Query OK, 0 rows affected (0.27 sec)
ユーザーに付与された権限を確認する
SHOW GRANTS
ステートメントを使用すると、ユーザーに付与されている権限を確認できます。例えば:
SHOW GRANTS; -- show grants for the current user
+-------------------------------------------------------------+
| Grants for User |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
SHOW GRANTS FOR 'root'@'%'; -- show grants for a specific user
たとえば、ユーザーrw_user@192.168.%
を作成し、そのユーザーにテーブルtest.write_table
に対する書き込み権限とグローバル読み取り権限を付与します。
CREATE USER `rw_user`@`192.168.%`;
GRANT SELECT ON *.* TO `rw_user`@`192.168.%`;
GRANT INSERT, UPDATE ON `test`.`write_table` TO `rw_user`@`192.168.%`;
rw_user@192.168.%
人のユーザーに付与された権限を表示します。
SHOW GRANTS FOR `rw_user`@`192.168.%`;
+------------------------------------------------------------------+
| Grants for rw_user@192.168.% |
+------------------------------------------------------------------+
| GRANT Select ON *.* TO 'rw_user'@'192.168.%' |
| GRANT Insert,Update ON test.write_table TO 'rw_user'@'192.168.%' |
+------------------------------------------------------------------+
動的な権限
v5.1 以降、TiDB 機能は、MySQL 8.0 から借用した機能である動的権限をサポートしています。動的権限は、特定の操作に対するよりきめ細かいアクセスを実装することにより、 SUPER
権限を置き換えることを目的としています。たとえば、システム管理者は、動的権限を使用して、 BACKUP
とRESTORE
操作のみを実行できるユーザー アカウントを作成できます。
動的権限には次のものが含まれます。
BACKUP_ADMIN
RESTORE_ADMIN
SYSTEM_USER
SYSTEM_VARIABLES_ADMIN
ROLE_ADMIN
CONNECTION_ADMIN
PLACEMENT_ADMIN
指定すると、権限所有者は配置ポリシーを作成、変更、削除できます。DASHBOARD_CLIENT
では、特権所有者が TiDB ダッシュボードにログインできるようになります。RESTRICTED_TABLES_ADMIN
指定すると、SEM が有効な場合、権限所有者はシステム テーブルを表示できます。RESTRICTED_STATUS_ADMIN
指定すると、SEM が有効な場合、特権所有者はSHOW [GLOBAL|SESSION] STATUS
のすべてのステータス変数を表示できます。RESTRICTED_VARIABLES_ADMIN
指定すると、SEM が有効な場合、権限所有者はすべてのシステム変数を表示できます。RESTRICTED_USER_ADMIN
SEM が有効な場合、特権所有者が SUPER ユーザーによってアクセスを取り消されることを禁止します。RESTRICTED_CONNECTION_ADMIN
指定すると、特権所有者はRESTRICTED_USER_ADMIN
人のユーザーの接続を強制終了できます。この権限はステートメントKILL
とステートメントKILL TIDB
に影響します。RESTRICTED_REPLICA_WRITER_ADMIN
指定すると、TiDB クラスターで読み取り専用モードが有効になっている場合、特権所有者は影響を受けることなく書き込みまたは更新操作を実行できます。詳細はtidb_restricted_read_only
を参照してください。
動的権限の完全なセットを表示するには、 SHOW PRIVILEGES
ステートメントを実行します。プラグインは新しい権限を追加できるため、割り当て可能な権限のリストは TiDB インストールによって異なる場合があります。
SUPER
特典
SUPER
権限により、ユーザーはほぼすべての操作を実行できます。デフォルトでは、root
ユーザーのみにこの権限が付与されます。この権限を他のユーザーに付与する場合は注意してください。SUPER
権限はMySQL 8.0 では非推奨になりましたとみなされ、よりきめ細かいアクセス制御を提供するために動的権限に置き換えることができます。
TiDB 操作に必要な権限
TiDB ユーザーの権限はINFORMATION_SCHEMA.USER_PRIVILEGES
表で確認できます。例えば:
mysql> SELECT * FROM INFORMATION_SCHEMA.USER_PRIVILEGES WHERE grantee = "'root'@'%'";
+------------+---------------+-------------------------+--------------+
| GRANTEE | TABLE_CATALOG | PRIVILEGE_TYPE | IS_GRANTABLE |
+------------+---------------+-------------------------+--------------+
| 'root'@'%' | def | Select | YES |
| 'root'@'%' | def | Insert | YES |
| 'root'@'%' | def | Update | YES |
| 'root'@'%' | def | Delete | YES |
| 'root'@'%' | def | Create | YES |
| 'root'@'%' | def | Drop | YES |
| 'root'@'%' | def | Process | YES |
| 'root'@'%' | def | References | YES |
| 'root'@'%' | def | Alter | YES |
| 'root'@'%' | def | Show Databases | YES |
| 'root'@'%' | def | Super | YES |
| 'root'@'%' | def | Execute | YES |
| 'root'@'%' | def | Index | YES |
| 'root'@'%' | def | Create User | YES |
| 'root'@'%' | def | Create Tablespace | YES |
| 'root'@'%' | def | Trigger | YES |
| 'root'@'%' | def | Create View | YES |
| 'root'@'%' | def | Show View | YES |
| 'root'@'%' | def | Create Role | YES |
| 'root'@'%' | def | Drop Role | YES |
| 'root'@'%' | def | CREATE TEMPORARY TABLES | YES |
| 'root'@'%' | def | LOCK TABLES | YES |
| 'root'@'%' | def | CREATE ROUTINE | YES |
| 'root'@'%' | def | ALTER ROUTINE | YES |
| 'root'@'%' | def | EVENT | YES |
| 'root'@'%' | def | SHUTDOWN | YES |
| 'root'@'%' | def | RELOAD | YES |
| 'root'@'%' | def | FILE | YES |
| 'root'@'%' | def | CONFIG | YES |
| 'root'@'%' | def | REPLICATION CLIENT | YES |
| 'root'@'%' | def | REPLICATION SLAVE | YES |
+------------+---------------+-------------------------+--------------+
31 rows in set (0.00 sec)
変更
- すべての
ALTER
ステートメントに対して、ユーザーは対応するテーブルに対するALTER
権限を持っている必要があります。 ALTER...DROP
とALTER...RENAME TO
を除くステートメントの場合、ユーザーは対応するテーブルに対するINSERT
とCREATE
権限を持っている必要があります。ALTER...DROP
ステートメントの場合、ユーザーは対応するテーブルに対するDROP
権限を持っている必要があります。ALTER...RENAME TO
ステートメントの場合、ユーザーは名前変更前にテーブルに対するDROP
権限を持ち、名前変更後のテーブルに対してCREATE
およびINSERT
権限を持っている必要があります。
ノート:
MySQL 5.7 のドキュメントでは、ユーザーがテーブルに対して
ALTER
操作を実行するにはINSERT
とCREATE
権限が必要です。しかし実際には、 MySQL 5.7.25 では、この場合に必要なのはALTER
権限のみです。現在、TiDB のALTER
権限は、MySQL の実際の動作と一致しています。
バックアップ
SUPER
またはBACKUP_ADMIN
権限が必要です。
データベースの作成
データベースに対するCREATE
権限が必要です。
インデックスの作成
テーブルに対するINDEX
権限が必要です。
テーブルの作成
テーブルに対するCREATE
権限が必要です。
CREATE TABLE...LIKE...
ステートメントを実行するには、テーブルに対するSELECT
権限が必要です。
ビューの作成
CREATE VIEW
権限が必要です。
ノート:
現在のユーザーがビューを作成するユーザーではない場合は、
CREATE VIEW
とSUPER
の両方の権限が必要です。
データベースを削除
テーブルに対するDROP
権限が必要です。
ドロップインデックス
テーブルに対するINDEX
権限が必要です。
ドロップテーブル
テーブルに対するDROP
権限が必要です。
データを読み込む
テーブルに対するINSERT
権限が必要です。 REPLACE INTO
使用する場合は、 DELETE
権限も必要です。
テーブルの切り捨て
テーブルに対するDROP
権限が必要です。
テーブルの名前を変更
名前変更前のテーブルにはALTER
およびDROP
権限が必要で、名前変更後のテーブルにはCREATE
およびINSERT
権限が必要です。
分析テーブル
テーブルに対するINSERT
およびSELECT
権限が必要です。
見せる
SHOW CREATE TABLE
は、テーブルに対する任意の 1 つの権限が必要です。
SHOW CREATE VIEW
はSHOW VIEW
権限が必要です。
SHOW GRANTS
は、 mysql
データベースに対するSELECT
権限が必要です。対象ユーザーが現在のユーザーの場合、 SHOW GRANTS
は特権は必要ありません。
SHOW PROCESSLIST
他のユーザーに属する接続を表示するにはSUPER
が必要です。
ロール/ユーザーの作成
CREATE ROLE
はCREATE ROLE
権限が必要です。
CREATE USER
はCREATE USER
権限が必要です。
ロール/ユーザーを削除
DROP ROLE
はDROP ROLE
権限が必要です。
DROP USER
はCREATE USER
権限が必要です。
ユーザーの変更
CREATE USER
権限が必要です。
許す
GRANT
によって付与される権限とともにGRANT
権限が必要です。
ユーザーを暗黙的に作成するには、追加のCREATE USER
権限が必要です。
GRANT ROLE
はSUPER
またはROLE_ADMIN
特権が必要です。
取り消す
GRANT
権限とREVOKE
ステートメントの対象となる権限が必要です。
REVOKE ROLE
はSUPER
またはROLE_ADMIN
特権が必要です。
グローバルに設定
グローバル変数を設定するにはSUPER
またはSYSTEM_VARIABLES_ADMIN
権限が必要です。
管理者
SUPER
権限が必要です。
デフォルトの役割を設定
SUPER
権限が必要です。
殺す
他のユーザーセッションを強制終了するには、 SUPER
またはCONNECTION_ADMIN
権限が必要です。
リソースグループの作成
SUPER
またはRESOURCE_GROUP_ADMIN
権限が必要です。
リソースグループの変更
SUPER
またはRESOURCE_GROUP_ADMIN
権限が必要です。
リソースグループを削除
SUPER
またはRESOURCE_GROUP_ADMIN
権限が必要です。
リソースの調整
SUPER
またはRESOURCE_GROUP_ADMIN
権限が必要です。
特権制度の導入
特権テーブル
次のシステム テーブルは、すべての権限関連データが格納されるため、特別です。
mysql.user
(ユーザーアカウント、グローバル権限)mysql.db
(データベースレベルの権限)mysql.tables_priv
(テーブルレベルの権限)mysql.columns_priv
(列レベルの権限。現在サポートされていません)
これらのテーブルには、データの有効範囲と権限情報が含まれています。たとえば、 mysql.user
テーブルでは次のようになります。
mysql> SELECT User,Host,Select_priv,Insert_priv FROM mysql.user LIMIT 1;
+------|------|-------------|-------------+
| User | Host | Select_priv | Insert_priv |
+------|------|-------------|-------------+
| root | % | Y | Y |
+------|------|-------------|-------------+
1 row in set (0.00 sec)
このレコードでは、 Host
とUser
により、 root
ユーザが任意のホスト( %
)から送信した接続要求を受け付け可能であることが判断される。 Select_priv
とInsert_priv
、ユーザーがグローバルSelect
とInsert
権限を持っていることを意味します。表mysql.user
の有効範囲はグローバルです。
mysql.db
のHost
とUser
によって、ユーザーがアクセスできるデータベースが決まります。有効範囲はデータベースです。
ノート:
特権テーブルは、
GRANT
、CREATE USER
、DROP USER
などの指定された構文を使用してのみ更新することをお勧めします。基礎となる権限テーブルを直接編集しても、権限キャッシュは自動的に更新されないため、FLUSH PRIVILEGES
が実行されるまで予測できない動作が発生します。
接続の検証
クライアントが接続リクエストを送信すると、TiDBサーバーはログイン操作を検証します。 TiDBサーバーは最初にmysql.user
テーブルをチェックします。レコードUser
とHost
接続リクエストと一致する場合、TiDBサーバーはレコードauthentication_string
を検証します。
ユーザー ID は 2 つの情報に基づいています。1 Host
接続を開始するホスト、 User
はユーザー名です。ユーザー名が空でない場合は、ユーザー名が完全に一致する必要があります。
User
+ Host
user
テーブルの複数の行に一致する可能性があります。このシナリオに対処するために、 user
のテーブルの行が並べ替えられます。クライアントが接続すると、テーブルの行が 1 つずつチェックされます。最初に一致した行が検証に使用されます。並べ替える場合、ホストはユーザーよりも優先されます。
検証のリクエスト
接続が成功すると、リクエスト検証プロセスによって、操作に権限があるかどうかがチェックされます。
データベース関連のリクエスト ( INSERT
、 UPDATE
) の場合、リクエスト検証プロセスは最初にテーブルmysql.user
内のユーザーのグローバル権限をチェックします。権限が付与されている場合は、直接アクセスできます。そうでない場合は、 mysql.db
表を確認してください。
user
テーブルには、デフォルトのデータベースに関係なくグローバル権限があります。たとえば、 user
のDELETE
権限は、任意の行、テーブル、またはデータベースに適用できます。
db
の表では、空のユーザーが匿名ユーザー名と一致します。 User
列にはワイルドカードを使用できません。 Host
とDb
列の値には、パターン マッチングを使用できる%
と_
を使用できます。
テーブルuser
とテーブルdb
のデータも、メモリにロードされるときにソートされます。
tables_priv
とcolumns_priv
での%
の使用は似ていますが、 Db
、 Table_name
、およびColumn_name
の列値に%
を含めることはできません。ロード時のソートも同様です。
効果時間
TiDB が起動すると、いくつかの権限チェック テーブルがメモリにロードされ、キャッシュされたデータを使用して権限が検証されます。 GRANT
、 REVOKE
、 CREATE USER
、 DROP USER
などの権限管理ステートメントを実行すると、すぐに有効になります。
mysql.user
などのテーブルをINSERT
、 DELETE
、 UPDATE
などのステートメントで手動で編集しても、すぐには有効になりません。この動作は MySQL と互換性があり、権限キャッシュは次のステートメントで更新できます。
FLUSH PRIVILEGES;