phpMyAdmin の設定で久しぶりにハマる!


phpMyAdmin とは

説明するまでも無いですね。
社内でもMySQLと言ったらphpMyAdminが常に使われているような、必須のDB管理ツールです。
AWSのRDSでも管理用に使うことが多いです。
セッティングも何十回、いやそれ以上設定しているはずですが、今回久しぶりに設定でハマりましたので記録として残します。

今回の環境は

  • CentOS7.6
  • Apache2.4
  • PHP 7.1
  • MariaDB 10.4
  • phpMyAdmin 4.9.0

となっています。

そうです、今回はMySQL ではなく 互換の MariaDB です。
ただし、今まで MariaDB を MySQL同様に使って問題が生じたことが無いほどの MySQL互換です。

まずは phpMyAdmin の起動確認。

特に問題ありません。

rootの初期パスワードは無し

次にログインユーザー名/パスワードの確認です。
MySQLはあるバージョン(5.7くらい?)から、rootユーザーの初期パスワードが自動的に割り振られ、MySQLインストール時に表示されたり、ログファイルに記載されたりしてますが、MariaDB10.4では初期パスワードは無しです。

ハマりどころですが、phpMyAdminがrootパスワード無しを受け付けるように設定ファイルを変更します。

config.inc.php
$cfg['Servers'][$i]['AllowNoPassword'] = true;

これで rootユーザーのパスワード無しでログインできるはずです。
早速入力してみます。

あれっ?

mysqli_real_connect(): (HY000/1698): Access denied for user 'root'@'localhost'

よく見るエラーです。

rootユーザーでmysqlログインできるかをコマンドラインで確認

ここでログインできなくてもあわてずに、コマンドラインでログインできるか確認します。
MariaDB でも MySQLと同じ mysqlコマンドです。

# mysql -u root
Welcome to the MariaDB monitor.  Commands end witYour MariaDB connection id is 8
Server version: 10.4.6-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corpora

Type 'help;' or '\h' for help. Type '\c' to clear

MariaDB [(none)]> quit
Bye
#

特に問題無いようです。次のステップに進みます。

PHPとMySQLのソケットの位置を確認

phpMyAdminは、接続先データベースがlocalhostの場合は、デフォルトでソケット接続になるようです。
つまり、ポート(標準3306番)を経由して接続するのではなく、ファイル(mysql.sock)経由になります。
ソケットファイルがどこにあるのかを探します。

# find / -name mysql.sock
/var/lib/mysql/mysql.sock
#

ソケットファイルの場所はわかりましたので、php.iniファイルでパスを設定します。

php.ini
mysqli.default_socket = /var/lib/mysql/mysql.sock

設定を有効にするために、Apacheを再起動します。

だいたいこれで解決するはずですが・・・

今回は・・・同じくログインできずエラー内容も変わりません。

MySQLの認証方法?

ここまでで今までは解決したはずですが、なぜか今回はログインできません。
色々情報を検索する中で、MySQL8.0以降では認証方式が異なる場合もあるという情報を見つけました。
userテーブルのPluginを確認してみます。

MariaDB [(none)]> SELECT user,password,plugin, authentication_string from mysql.user;
+-------+----------+-----------------------+-----------------------+
| User  | Password | plugin                | authentication_string |
+-------+----------+-----------------------+-----------------------+
| root  | invalid  | mysql_native_password | invalid               |
| mysql | invalid  | mysql_native_password | invalid               |
|       |          |                       |                       |
|       |          |                       |                       |
+-------+----------+-----------------------+-----------------------+
4 rows in set (0.003 sec)

MariaDB [(none)]>

このpluginが、mysql_native_passwordで無ければ、

ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password';

として、pluginを変更すればいいのですが、mysql_native_passwordが指定されているので違います。

もう八方塞がりになってきましたが、Passwordauthentication_stringinvalidなのが気になります。
それでもパスワードは設定していませんし、コマンドラインからはログインできますし。。。

ユーザーの違いにより不思議な挙動を発見

今まではサーバーのインストール直後ということもあり、rootユーザーで操作してきました。
一息置いて、一般ユーザーアカウントのuserでログインして、mysqlコマンドを実行してみました。

$ mysql -u root 
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
$ 

あらら?ログインできたはず。

もしかしたら、

$ sudo mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 20
Server version: 10.4.6-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

おー、やっぱりrootユーザーではログインできました。

ユーザー権限によってログインできたりできなかったりするということは、ソケットアクセスがユーザー権限により異なるということが予想されます。
現象はわかりましたが、解決方法はわからず。

やっと解決

もう対処のしようが無いと思いましたが、Passwordフィールドがinvalidなのが気になります。
パスワードを設定していないのですから、本来、空(NULL)であるべきです。
そうだ、パスワードを再設定してみよう!

set password for root@localhost=password('');

元々パスワード無しなのですが、再度パスワード無しで設定します。

MariaDB [(none)]> SELECT user,password,plugin, authentication_string from mysql.user;
+-------+----------+-----------------------+-----------------------+
| User  | Password | plugin                | authentication_string |
+-------+----------+-----------------------+-----------------------+
| root  | invalid  | mysql_native_password | invalid               |
| mysql | invalid  | mysql_native_password | invalid               |
|       |          |                       |                       |
|       |          |                       |                       |
+-------+----------+-----------------------+-----------------------+
4 rows in set (0.002 sec)

MariaDB [(none)]> set password for root@localhost=password('');
Query OK, 0 rows affected (0.002 sec)

MariaDB [(none)]> SELECT user,password,plugin, authentication_string from mysql.user;
+-------+----------+-----------------------+-----------------------+
| User  | Password | plugin                | authentication_string |
+-------+----------+-----------------------+-----------------------+
| root  |          | mysql_native_password |                       |
| mysql | invalid  | mysql_native_password | invalid               |
|       |          |                       |                       |
|       |          |                       |                       |
+-------+----------+-----------------------+-----------------------+
4 rows in set (0.002 sec)

MariaDB [(none)]> flush privileges;

Passwordフィールドだけではなく、authentication_stringもきれいになりました。

この状態でブラウザから、phpMyAdminにアクセスしてみます。

おー、ちゃんと表示されました。

理由もわからず、MariaDBだからなのかわかりませんが、とりあえず解決です。

同様の事例も後から見つけました。
serverfault(https://serverfault.com/questions/795290/admin-password-of-mariadb-doesnt-seem-to-work)