First Creation | 2005/02/12 |
---|---|
Last Update | 2007/02/05 |
ユーザーを追加したものの、実はまだセキュリティ的に不安が残る。なぜなら前回追加したユーザーは、スーパーユーザーに匹敵するほどの過剰な権限を与えられているのである。しかも、全てのデータベースにアクセスできる。これはとても危険なことだ。
本当は test というデータベースだけ操作できればいいのに、重要なデータベースに対してあらゆる操作ができてしまう。
他のユーザの(ZAURUS は一人で使っているからありえないが)データベースを閲覧したり、改ざんしたり、MySQL の管理者である root もしくは Administrator が削除されてしまうことだってあり得る。
そこで MySQL のユーザーに対し、特定のデータベースしか操作できないようにしてみた。
さらに、データベースに対する操作(コマンド)も制限してみよう。
アクセス権限は mysql データベースの db テーブルに保存される。
mysql> use mysql; Database changed mysql> show tables; +-----------------+ | Tables in mysql | +-----------------+ | columns_priv | | db | | func | | host | | tables_priv | | user | +-----------------+ 6 rows in set (0.00 sec)
では、db テーブルのカラムを見てみよう。
mysql> describe db; +-----------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------------+---------------+------+-----+---------+-------+ | Host | char(60) | | PRI | | | | Db | char(32) | | PRI | | | | User | char(16) | | PRI | | | | Select_priv | enum('N','Y') | | | N | | | Insert_priv | enum('N','Y') | | | N | | | Update_priv | enum('N','Y') | | | N | | | Delete_priv | enum('N','Y') | | | N | | | Create_priv | enum('N','Y') | | | N | | | Drop_priv | enum('N','Y') | | | N | | | Grant_priv | enum('N','Y') | | | N | | | References_priv | enum('N','Y') | | | N | | | Index_priv | enum('N','Y') | | | N | | | Alter_priv | enum('N','Y') | | | N | | +-----------------+---------------+------+-----+---------+-------+ 13 rows in set (0.00 sec)
mysql データベースの user テーブルにはなかった Db というこカラムが存在する。これがデータベースへの権限を保存しておくための場所らしい。
どんなユーザーが存在するか、SELECT コマンドで確認してみる。
mysql> select user,host,db from db; +------+------+---------+ | user | host | db | +------+------+---------+ | | % | test | | | % | test\_% | +------+------+---------+ 2 rows in set (0.00 sec)
空のユーザがあるではないか。どうやら test データベースにアクセスするためのユーザーらしい。
不要な空ユーザを削除する。
mysql> delete from mysql.user where user=""; Query OK, 2 rows affected (0.01 sec) mysql> select user,host,db from db; Empty set (0.00 sec)
test データベースは不要なので削除する。
mysql> drop database test; Query OK, 0 rows affected (0.00 sec) mysql> show databases; +----------+ | Database | +----------+ | mysql | | user_db | +----------+ 2 rows in set (0.00 sec)
mysql と user_db データベースのみ残った。
bloody というデータベースを作成する一方、mary というユーザーを作成し、bloody への全権限を付与する。
mysql> create database bloody; Query OK, 1 row affected (0.00 sec) mysql> show databases; +----------+ | Database | +----------+ | bloody | | mysql | | user_db | +----------+ 3 rows in set (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)
mysql> grant all on bloody.* to mary@localhost identified by "my_password" with grant option; Query OK, 0 rows affected (0.01 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)
とりあえずは全権限を付与してしまう。
「flush privileges;」はリロードの呪文だ。ユーザーを追加したり削除したりしたら唱えておいた方がいい。それほど手間ではないだろうし。
mysql> select host,user,password from mysql.user; +-----------+---------------+------------------+ | host | user | password | +-----------+---------------+------------------+ | localhost | mary | 3c21f78362fdb84c | | localhost | Administrator | 442455895eac74e7 | +-----------+---------------+------------------+ 2 rows in set (0.01 sec) mysql> select * from mysql.user; +-----------+---------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+ | Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | +-----------+---------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+ | localhost | mary | 3c21f78362fdb84c | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | localhost | Administrator | 442455895eac74e7 | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +-----------+---------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+ 2 rows in set (0.00 sec) mysql> select * from db; +-----------+--------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+ | Host | Db | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv | +-----------+--------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+ | localhost | bloodY | mary | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +-----------+--------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+ 1 row in set (0.00 sec)
ちなみに、上記の検索結果は、1280 * 1024 のモニタが2 つないと、折り返さず表示することはできない。おかげで分かりづらいことこの上ない。ナメてんのか・・・
気を取り直して、「select * from mysql.user;」で、mary の権限がすべて N になっている。これは、mary というユーザでは、user データベースは一切操作ができない、ということを表している。
一方、「select * from db;」 を実行すると、mary の権限がすべて Y になっているのが確認できる。これは、mary というユーザが、bloody というテーブルに対して、全ての権限を持っている、ということを表している。
この状態で exit し、mary で MySQL を使ってみよう。
# mysql -u mary -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 43 to server version: 3.22.32-log Type help for help. mysql> show databases; +----------+ | Database | +----------+ | bloody | | mysql | | user_db | +----------+ 3 rows in set (0.00 sec) mysql> use mysql; ERROR 1044: Access denied for user: 'mary@localhost' to database 'mysql'
mary で mysql を使おうとすると、ちゃんと Access denied されてる。
逆に、bloody データベースに対しては何でもできてしまう。ちょっと権限を与えすぎた気もするが、これでよしとしよう。