2015年2月4日水曜日

MySQL 5.7.5 on Windowsでskip-name-resolveするとrootでログインできなくなる

ことの発端はこのバグレポート。

MySQL Bugs: #75656: 5.7.5 skip_name_resolve stops all connection attempts

なんでかよくわからないけれど、調べてみようと思った。そしたらば。


mysql57> SELECT user, host FROM mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | localhost |
+------+-----------+
1 row in set (0.00 sec)

mysql_install_dbして起動しただけでコレ。これじゃあ--skip-name-resolveしたらつながらなくなるだろうという感じ。

日々の覚書: user@localhostとuser@127.0.0.1は別人?

MySQL Bugs: #68436: user@127.0.0.1 is authorized partly as user@localhost.

* Linuxでは--protocolを指定しない場合は暗黙で--protocol=socketになるんですが、Windowsでは指定しない場合は暗黙で--protocol=tcpになるんです。豆知識。
* 名前解決が有効な時は接続元: 127.0.0.1を接続元: localhostにリバースマップしてくれて--protocol=tcpでも認証が通るんですが、skip-name-resolveしてるとこの逆引きを一切してくれないので、127.0.0.1 ≠ localhostという単純な比較がなされて認証に失敗します。


$ bin/mysql_install_db --basedir=./ --datadir=data --verbose=1
2015-02-04 17:13:08 [NOTE]    Creating data directory data
2015-02-04 17:13:08 [NOTE]    Generating random password to /home/yoku0825/.mysql_secret...done.
2015-02-04 17:13:08 [NOTE]    Executing /usr/mysql/5.7.5/bin/mysqld --no-defaults --bootstrap --datadir=data --lc-messages-dir=./share --lc-messages=en_US --basedir=.
2015-02-04 17:13:11 [NOTE]    Creating system tables...done.
2015-02-04 17:13:11 [NOTE]    Filling system tables with data...done.
2015-02-04 17:13:12 [NOTE]    Filling help table with data...done.
2015-02-04 17:13:12 [NOTE]    Creating default user root@localhost
2015-02-04 17:13:12 [NOTE]    Creating default proxy root@localhost
2015-02-04 17:13:13 [NOTE]    Success!



mysql-5.7.5-m15/client/mysql_install_db.cc を参照すると(MySQL 5.7.5からmysql_install_dbはC++で書かれているのだ)

296 struct Sql_user
297 {
..
348 void to_sql(string *cmdstr)
349 {
350 stringstream set_oldpasscmd,ss;
351 ss << "INSERT INTO mysql.user VALUES (" 352 << "'" << escape_string(host) << "','" << escape_string(user) << "',"; ..

ユーザーを作るためのINSERTステートメントはこのへんで組み立てていて、


940 class Process_writer
941 {
942 public:
943 Process_writer(Sql_user *user, const string &opt_sqlfile) : m_user(user),
944 m_opt_sqlfile(opt_sqlfile) {}
945 bool operator()(int fh)
946 {
..
1003 info << "Creating default user " << m_user->user << "@" 1004 << m_user->host
1005 << endl; 1006 string create_user_cmd; 1007 m_user->to_sql(&create_user_cmd);
1008 write(fh, create_user_cmd.c_str(), create_user_cmd.length());
..

それを読んでるのはここで1回のみ。その元になるのはどこから来るかというと、ぐるぐる探し迷った末に


122 {"admin-user", 0, "Username part of the default admin account.",
123 &opt_adminuser, 0, 0, GET_STR_ALLOC, REQUIRED_ARG,
124 (longlong)&default_adminuser, 0, 0, 0, 0, 0},
125 {"admin-host", 0, "Hostname part of the default admin account.",
126 &opt_adminhost, 0, 0, GET_STR_ALLOC,REQUIRED_ARG,
127 (longlong)&default_adminhost, 0, 0, 0, 0, 0},

ここにたどり着いた。


$ ./bin/mysql_install_db --basedir=./ --datadir=data --admin-user=root --admin-host=127.0.0.1 --verbose=1
2015-02-04 18:46:29 [NOTE]    Creating data directory data
2015-02-04 18:46:29 [NOTE]    Generating random password to /home/yoku0825/.mysql_secret...done.
2015-02-04 18:46:29 [NOTE]    Executing /usr/mysql/5.7.5/bin/mysqld --no-defaults --bootstrap --datadir=data --lc-messages-dir=./share --lc-messages=en_US --basedir=.
2015-02-04 18:46:31 [NOTE]    Creating system tables...done.
2015-02-04 18:46:31 [NOTE]    Filling system tables with data...done.
2015-02-04 18:46:32 [NOTE]    Filling help table with data...done.
2015-02-04 18:46:32 [NOTE]    Creating default user root@127.0.0.1
2015-02-04 18:46:32 [NOTE]    Creating default proxy root@127.0.0.1
2015-02-04 18:46:33 [NOTE]    Success!

大正解。--admin-hostで指定してやればOKぽいので、


*** client/mysql_install_db.cc  2014-09-18 22:36:41.000000000 +0900
--- client/mysql_install_db.cc.new      2015-02-04 18:49:16.113066355 +0900
***************
*** 65,71 ****
  char *opt_sqlfile= 0;
  char default_adminuser[]= "root";
  char *opt_adminuser= 0;
! char default_adminhost[]= "localhost";
  char *opt_adminhost= 0;
  char default_authplugin[]= "mysql_native_password";
  char *opt_authplugin= 0;
--- 65,75 ----
  char *opt_sqlfile= 0;
  char default_adminuser[]= "root";
  char *opt_adminuser= 0;
! #ifdef __WIN__
!   char default_adminhost[]= "127.0.0.1";
! #else
!   char default_adminhost[]= "localhost";
! #endif
  char *opt_adminhost= 0;
  char default_authplugin[]= "mysql_native_password";
  char *opt_authplugin= 0;

Windowsだったら127.0.0.1にするとか、こんなパッチでいいのかな? (ウインドーズでMySQLビルドしたことないからよくわからない。。) とりあえずBugsは更新しておいた。ワークアラウンドとパッチと。

0 件のコメント :

コメントを投稿