TL;DR
MySQL 5.6とそれ以前のはなし。5.7とそれ以降はこの初期設定は入っていない。
- MySQL 5.6でもインストール方法によっては存在しないし mysql_secure_installation を使った場合はこの設定は消されるし、MySQL 5.7とそれ以降だろうと5.6からインプレースアップグレードやmysqlスキーマまで含めたフルリストアでアップグレードした場合は設定は残っているだろう
昔のMySQLは
test
というスキーマをmysql_install_db
で作ってしまって、しかもこのスキーマは全アカウントに対して(ストアド以外の)読み書き権限があるGRANT USAGE
しかないアカウントでも平気でCREATE TABLE
もINSERT
も一通りできるついでに言うと
test
スキーマだけじゃなくてtest_1
スキーマにも同じことができる。test_*
のパターンを持つスキーマなら全部そう
DROP DATABASE test
したところで、誰にでもCREATE DATABASE test
する権限があるので、そんなことより権限を剥がす方が先DELETE mysql.db WHERE user = '' AND host = '%'; FLUSH PRIVILEGES;
かな
MySQL 5.6は2021/2/1で EOL になっているので、そもそも使わない方が良いだろうし、今日日の5.6とそれ以前限定の話をするのもどうかなとは思っている。が、アップグレードの仕方によってはこの設定は残っているので注意。
取り敢えず、5.6.51の吊るしの mysql_install_db
でdatadirを初期化する。
$ ./scripts/mysql_install_db --datadir=/usr/mysql/5.6.51/data
Installing MySQL system tables...2021-09-15 15:11:03 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
2021-09-15 15:11:03 0 [Note] ./bin/mysqld (mysqld 5.6.51-log) starting as process 4634 ...
OK
Filling help tables...2021-09-15 15:11:05 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
2021-09-15 15:11:05 0 [Note] ./bin/mysqld (mysqld 5.6.51-log) starting as process 4666 ...
OK
..
$ mysql56
mysql56> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
この test
スキーマができる。最近5.6とか使わないから久々に見たよ。
mysql56> CREATE USER yoku0825@localhost;
Query OK, 0 rows affected (0.00 sec)
コイツがどう悪いのかを試すために、何も権限を持っていないアカウントを作ってみる。
$ mysql56 -uyoku0825
mysql56> SHOW GRANTS;
+----------------------------------------------+
| Grants for yoku0825@localhost |
+----------------------------------------------+
| GRANT USAGE ON *.* TO 'yoku0825'@'localhost' |
+----------------------------------------------+
1 row in set (0.01 sec)
mysql56> use test
Database changed
mysql56> CREATE TABLE t1 (num int);
Query OK, 0 rows affected (0.02 sec)
mysql56> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
フツーに CREATE TABLE
できてしまった。これはいけない?
というか何の権限もないのに、この test
スキーマをDROPすることももう一度CREATEすることもできる。
mysql56> DROP DATABASE test;
Query OK, 1 row affected (0.00 sec)
mysql56> CREATE DATABASE test;
Query OK, 1 row affected (0.00 sec)
mysql56> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test |
+--------------------+
2 rows in set (0.00 sec)
それどころか、 test_
で始まるスキーマ名なら好きなようにできる。
mysql56> CREATE DATABASE test_yoku0825;
Query OK, 1 row affected (0.00 sec)
mysql56> ALTER DATABASE test_yoku0825 CHARSET utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql56> SHOW CREATE DATABASE test_yoku0825;
+---------------+---------------------------------------------------------------------------+
| Database | Create Database |
+---------------+---------------------------------------------------------------------------+
| test_yoku0825 | CREATE DATABASE `test_yoku0825` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
+---------------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql56> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test |
| test_yoku0825 |
+--------------------+
3 rows in set (0.00 sec)
まれにだがよく(?) 「 test
スキーマあるのいけないんで、DROPしてください」みたいな文面があるが、こんなもの消しても何の意味もなくて、この「SHOW GRANTSでは何も見えない何の権限も持っていないはずのアカウントが test
スキーマを好きなようにできる」設定の方を何とかしないといけない。
ちなみにこの権限の根源は mysql.db
テーブルにある。rootでログインしなおしてクエリーたたいてみる。
mysql56> SELECT * FROM mysql.db;
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| Host | Db | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Create_tmp_table_priv | Lock_tables_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Execute_priv | Event_priv | Trigger_priv |
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| % | test | | Y | Y | Y | Y | Y | Y | N | Y | Y | Y | Y | Y | Y | Y | Y | N | N | Y | Y |
| % | test\_% | | Y | Y | Y | Y | Y | Y | N | Y | Y | Y | Y | Y | Y | Y | Y | N | N | Y | Y |
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
2 rows in set (0.00 sec)
空白のuserは「任意のuser」、hostの ‘%’ は任意のホスト。
この2行の設定により、 test
スキーマと test_
で始まる任意のスキーマはほとんどのスキーマレベル権限を全アカウントに与えている。
mysql_secure_installation
はこの2行を消してから FLUSH PRIVILEGES
することでこの権限を消している。
https://github.com/mysql/mysql-server/blob/mysql-5.6.51/scripts/mysql_secure_installation.pl.in#L253
rootで消してから FLUSH PRIVILEGES
mysql56> DELETE FROM mysql.db WHERE user = '' AND host = '%';
Query OK, 2 rows affected (0.00 sec)
mysql56> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
これで期待通りの動きになる。
$ mysql56 -uyoku0825
mysql56> SHOW GRANTS;
+----------------------------------------------+
| Grants for yoku0825@localhost |
+----------------------------------------------+
| GRANT USAGE ON *.* TO 'yoku0825'@'localhost' |
+----------------------------------------------+
1 row in set (0.00 sec)
mysql56> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
mysql56> use test;
ERROR 1044 (42000): Access denied for user 'yoku0825'@'localhost' to database 'test'
ただし、既存のコネクションは use
でカレントデータベースを変えるか再接続しないと権限の変更は有効にはならないので、万全を期すならいったん再起動しておくと完璧だと思う。
0 件のコメント :
コメントを投稿