ユーザー作成のトラブル
MyAQL初心者でユーザー作成の勉強をするときなどに陥りやすい罠です。
rootでユーザーを作成
CREATE USER 'boku' IDENTIFIED BY '1234';
rootが作成したmydbの権限を与える
GRANT ALL ON mydb.* TO 'boku';
一般ユーザーでログイン
mysql -u boku -p;
ここまではうまくいきます。
次の場合に問題が起こります。
かなり以前のこと、rootで同じ名前のユーザーを作成。
どこかのブログを読んで丁寧にlocalhostのホスト名をつけてユーザーを作っていたとする。
けれどもこのユーザーの存在はすっかり忘れているとする。
CREATE USER 'boku'@'localhost' IDENTIFIED BY '1234';
ホスト名のない一般ユーザーでログインしようとしても入れないで以下エラーが出る。
mysql -u boku -p;
ERROR 1045 (28000): Access denied for user ‘boku’@’localhost’ (using password: YES)
色々やってみるが、なぜか‘@’localhost’が勝手に付けられている。
このような場合は、一旦rootになってユーザー一覧を確認してみる。
SELECT user, host FROM mysql.user;
次のようになっていると@’localhost’が追加されるようだ。
+——————+———–+
| user | host |
+——————+———–+
| boku | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| boku | localhost |
+——————+———–+
この場合は以前作成したホスト名付きユーザーを削除すると良いです。
DROP USER 'boku'@'localhost';
ユーザー名だけにするか、ホスト名を付けるかしっかりと理解しておく必要があります。
MySQLユーザー作成について
MySQLのユーザーを作成するときに、ホスト名を付けることで、そのユーザーが接続できるホストを限定できます。つまり、どのホストから接続された場合にそのユーザーが認証されるかを制限できるということです。
例えば、以下のようにホスト名を指定してユーザーを作成した場合、”user1″ユーザーは”example.com”からの接続のみを受け付け、他のホストからの接続は拒否されます。
CREATE USER 'user1'@'example.com' IDENTIFIED BY 'password';
一方、ホスト名を省略した場合、そのユーザーはどのホストからでも接続を受け付けることができます。以下のように、どのホストからでも接続を受け付けるユーザーを作成することができます。
CREATE USER 'user2' IDENTIFIED BY 'password';
ただし、セキュリティ上の理由から、ホスト名を省略したユーザーを作成する場合は注意が必要です。なるべく限定的なホスト名を指定することが推奨されます。また、不必要な権限を付与しないようにすることも重要です。
MySQLにおいてホスト名を省略した場合、デフォルトで「%」が設定されます。つまり、以下のように記述した場合:
CREATE USER 'user2' IDENTIFIED BY 'password';
実際には以下のように解釈されます:
CREATE USER 'user2'@'%' IDENTIFIED BY 'password';
これにより、”user2″ユーザーはどのホストからでも接続を受け付けることができるようになります。ただし、先述の通り、セキュリティ上の理由から、なるべく限定的なホスト名を指定することが推奨されます。
今回のケース
MySQLクライアントでユーザー名とホスト名を指定して接続する場合、シングルクオート(‘)で囲んだ文字列が不足している場合、MySQLクライアントは自動的にホスト名を’localhost’に置き換える傾向があります。これ結構ハマる。
例えば、以下のように’user1’@’%’というユーザーで接続しようとした場合:
mysql -u 'user1'@'%' -p
MySQLクライアントは、ホスト名が不足していると解釈し、’localhost’を補完した上で接続を試みます。つまり、実際に実行されるコマンドは以下のようになります:
mysql -u 'user1'@'localhost' -p
このため、’user1’@’%’で接続するには、シングルクオートで囲んだ文字列を完全に指定する必要があります。例えば、以下のように指定することで正しく接続できます。
解決策はこれ!
mysql -u 'user1'@'%' -h '%' -p
このように、-hオプションを使用して明示的にホスト名を指定することで、正しくユーザー名とホスト名を指定した接続が可能になります。