おいしい健康 開発者ブログ

株式会社おいしい健康で働くエンジニア・デザイナーが社内の様子をお伝えします。

MySQLにユーザーと権限を設定する

MySQLにユーザーを追加する機会がありましたので、ユーザー作成と権限追加について復習しました。
MySQL 5.6で動作確認しています。

dockerを使い、動作確認用のコンテナを起動します。 簡単に捨てられる環境が使えるのは便利ですね。

$ docker run -e MYSQL_ROOT_PASSWORD=password -p 13306:3306 --rm mysql:5.6

一通りログが流れきったら使えるようになります。 mysqlコマンドで母艦からmysqlにアクセスします。

$ mysql -u root -p -h 127.0.0.1 -P 13306

まずはユーザー一覧を表示します。

mysql> select Host, User from mysql.user;
+-----------+------+
| Host      | User |
+-----------+------+
| %         | root |
| localhost | root |
+-----------+------+

何も設定していないのでrootしかいない状態です。検証用のユーザーを作成します。

mysql> create user writable identified by 'hogehogehoge';

hogehogehogewritableユーザーのパスワードです。ユーザーを作成したので権限を確認してみます。

mysql> show grants for writable;
+---------------------------------------------------------------------------------------------------------+
| Grants for writable@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'writable'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
+---------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

USAGEは権限なしを表します。この辺に権限の説明があります。 https://dev.mysql.com/doc/refman/5.6/ja/privileges-provided.html

rootの権限は*.*を対象にALL PRIVILEGESをもっているので、すべての権限をもっています。

mysql> show grants for root;
+--------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@%                                                                                                              |
+--------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
+--------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

権限を付与するためのデータベースを作成します。

mysql> create database hoge;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

hogeデータベースが作成されました。

この時点でwritableユーザーでログインしてデータベース一覧を表示してもinformation_schemaしか表示されません。

$ mysql -u writable -p -h 127.0.0.1 -P 13306
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

writableユーザーにhogeデータベースの全ての権限を付与します。

mysql> grant all privileges on hoge.* to writable@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for writable;
+---------------------------------------------------------------------------------------------------------+
| Grants for writable@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'writable'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
| GRANT ALL PRIVILEGES ON `hoge`.* TO 'writable'@'%'                                                      |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

これでwritableユーザーが自由にhogeデータベースを操作できるようになりました。 再びwritableユーザーでログインしてデータベース一覧を見るとhogeデータベースが表示されます。

$ mysql -u writable -p -h 127.0.0.1 -P 13306
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
+--------------------+
2 rows in set (0.00 sec)

テーブルを作り、レコードをいくつか追加します。

mysql> create table users(
    ->   id int auto_increment not null primary key,
    ->   name varchar(32)
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql> insert into users(name) values('Taro'),('Hanako'),('Jiro');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | Taro   |
|  2 | Hanako |
|  3 | Jiro   |
+----+--------+
3 rows in set (0.00 sec)

再びrootに戻り、今度はreadonlyユーザーを追加します。 読み込みだけできればいいので、SELECT権限だけ付与します。

mysql> create user readonly identified by 'hogehogehoge';
Query OK, 0 rows affected (0.00 sec)

mysql> grant select on hoge.* to readonly@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for readonly;
+---------------------------------------------------------------------------------------------------------+
| Grants for readonly@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'readonly'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
| GRANT SELECT ON `hoge`.* TO 'readonly'@'%'                                                              |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

ユーザーの作成ができたので、動作確認してみます。

$ mysql -u readonly -p -h 127.0.0.1 -P 13306

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
+--------------------+
2 rows in set (0.00 sec)

mysql> use hoge;
Database changed
mysql> show tables;
+----------------+
| Tables_in_hoge |
+----------------+
| users          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | Taro   |
|  2 | Hanako |
|  3 | Jiro   |
+----+--------+
3 rows in set (0.00 sec)

mysql> insert into users(name) values('Saburou');
ERROR 1142 (42000): INSERT command denied to user 'readonly'@'172.17.0.1' for table 'users'

select文で内容を表示することはできましたが、insert文を実行することはできませんでした。

以上です。