2013年2月25日月曜日

user@localhostとuser@127.0.0.1は別人?

ある日SH2先生がつぶやきました。
個人的には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)

mysql55> show grants;
+-------------------------------------------------------------------------------------------------------------+
| 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のあるなしでアクセス可能な領域が変わってくる。
これ、IPアドレスの方がネットマスク形式だったりワイルドカード使ってたりすると結構悲惨かも。。

心当たりのある方は、運用途中で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


おうい。。大丈夫かねこれ。。

↓↓理屈としてはこうらしいですが。。

これ`Not a Bug'らしいですよ!
マニュアルにもうちょっと詳細記載してよ!」って投稿でしたが、ヌルーされてますねー。。

SH2さんに「ネタにして良いよ!」と快諾いただいたのでネタにさせていただきましたm(_"_)m
ありがとうございますー。

0 件のコメント :

コメントを投稿