127.0.0.1で接続したクライアントがlocalhostで認証されるらしい。再現しない
— SH2さん (@sh2nd) 2013年2月19日
mysql.userにlocalhostのみがある場合、localhost (UNIX Socket)、127.0.0.1 (TCP/IP)は両方接続できる。mysql.userに127.0.0.1のみがある場合、localhost (UNIX Socket)では接続できない
— SH2さん (@sh2nd) 2013年2月19日
GRANT ALL PRIVILEGES ON db1.* TO test1(at)localhost、GRANT ALL PRIVILEGES ON db2.* TO test1(at)127.0.0.1 ってやったときに、
— SH2さん (@sh2nd) 2013年2月19日
(続き) mysql -u test1 -h localhost db2 は通らないけど mysql -u test1 -h 127.0.0.1 db1 は通ってしまう
— SH2さん (@sh2nd) 2013年2月19日
これの(e)~(h)の挙動が本当にこれでいいのか考えている。特に(g) dbstudy.info/temp/localhost…
— SH2さん (@sh2nd) 2013年2月19日
個人的にはMySQLのlocalhost ≠ 127.0.0.1と言われて育った世代なので、どうもしっくり来ない。。mysqlクライアントもDBIで叩くときも(libmysqlclient.soの実装なのかDBI側の実装なのか知らないけど、PerlとPHPは少なくとも)
localhostだとsocketを叩きにいくし、127.0.0.1はTCPソケットを叩きにいく。
host部が違うのでパスワードも違うし、SHOW GRANTSの結果も違う = 別のユーザー って認識だったんですが。。
SH2さんがその流れで上げてくれたBugs
Bug #68436 user@127.0.0.1 is authorized partly as user@localhost.
と、マニュアル
http://dev.mysql.com/doc/refman/5.6/en/access-denied.html
http://dev.mysql.com/doc/refman/5.6/en/request-access.html
を読み比べてみると、
localhostは127.0.0.1ではないが、127.0.0.1はlocalhost(ややこし)
って感じだろうか。。
テストケースが付いているのでさそのまま試してみる。
GRANT ALL PRIVILEGES ON db1.* TO user@localhost IDENTIFIED BY 'pass1';
GRANT ALL PRIVILEGES ON db2.* TO user@127.0.0.1 IDENTIFIED BY 'pass2';
CREATE DATABASE db1;
CREATE DATABASE db2;
としてから、
$ mysql55 -h127.0.0.1 -uuser -ppass1
..
mysql55> select current_user();
+----------------+
| current_user() |
+----------------+
| user@localhost |
+----------------+
1 row in set (0.00 sec)
+-------------------------------------------------------------------------------------------------------------+
| Grants for user@localhost |
+-------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY PASSWORD '*22A99BA288DB55E8E230679259740873101CD636' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'user'@'localhost' |
+-------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql55> use db2
Database changed
mysql55> create table tbl1 ( num serial );
Query OK, 0 rows affected (0.34 sec)
mysql55> show create table tbl1;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------+
| tbl1 | CREATE TABLE `tbl1` (
`num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
おー、行った行った。変な感じ。
これって、skip-name-resolveのあるなしで、
【skip-name-resolveしてない】
$ mysql -uu1 -h192.168.199.131
..
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| u1@mysqlha01 |
+----------------+
1 row in set (0.00 sec)
mysql> show grants;
+----------------------------------------------------+
| Grants for u1@mysqlha01 |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO 'u1'@'mysqlha01' |
| GRANT ALL PRIVILEGES ON `d1`.* TO 'u1'@'mysqlha01' |
+----------------------------------------------------+
2 rows in set (0.00 sec)
mysql> use d1;
Database changed
mysql> use d2;
Database changed
【skip-name-resolveあり】
$ mysql -uu1 -h192.168.199.131
..
mysql> select current_user();
+--------------------+
| current_user() |
+--------------------+
| u1@192.168.199.131 |
+--------------------+
1 row in set (0.00 sec)
mysql> show grants;
+----------------------------------------------------------+
| Grants for u1@192.168.199.131 |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO 'u1'@'192.168.199.131' |
| GRANT ALL PRIVILEGES ON `d2`.* TO 'u1'@'192.168.199.131' |
+----------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> use d1;
ERROR 1044 (42000): Access denied for user 'u1'@'192.168.199.131' to database 'd1'
mysql> use d2;
Database changed
やっぱりこうなるよねー。。
GRANT(mysqlスキーマ)の段階でカブリがあると、
skip-name-resolveのあるなしでアクセス可能な領域が変わってくる。
skip-name-resolveのあるなしでアクセス可能な領域が変わってくる。
これ、IPアドレスの方がネットマスク形式だったりワイルドカード使ってたりすると結構悲惨かも。。
心当たりのある方は、運用途中でskip-name-resolveをつける時は…って、
mysql.userにホスト名書いてある状態でskip-name-resolveは設定しないか。。
mysql.userにホスト名書いてある状態でskip-name-resolveは設定しないか。。
更についでに、skip-name-resolveを付けたり外したりして再起動していたら、
$ mysql -uu1 -h192.168.199.131
..
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| u1@mysqlha01 |
+----------------+
1 row in set (0.00 sec)
mysql> show variables like '%resolv%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| skip_name_resolve | OFF |
+-------------------+-------+
1 row in set (0.00 sec)
mysql> use d1;
Database changed
mysql> use d2;
Database changed
..
$ mysql -uu1 -hmysqlHA01
mysql> select current_user();
+--------------------+
| current_user() |
+--------------------+
| u1@192.168.199.131 |
+--------------------+
1 row in set (0.00 sec)
mysql> show variables like '%resolv%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| skip_name_resolve | OFF |
+-------------------+-------+
1 row in set (0.00 sec)
mysql> use d1;
Database changed
mysql> use d2;
Database changed
おうい。。大丈夫かねこれ。。
↓↓理屈としてはこうらしいですが。。
sql_acl.ccに「All host names without wild cards are stored in a hash table,」って書いてあるけどハッシュのご機嫌次第なのかなあ
— SH2さん (@sh2nd) 2013年2月19日
これ`Not a Bug'らしいですよ!
「マニュアルにもうちょっと詳細記載してよ!」って投稿でしたが、ヌルーされてますねー。。
SH2さんに「ネタにして良いよ!」と快諾いただいたのでネタにさせていただきましたm(_"_)m
ありがとうございますー。