MySQL 8.0 から デフォルトのパスワードの仕組みが caching_sha2_password に変更されました。
これに関連して、yoku0825 さんが以下のエントリーを掲載してます。
yokuさんのエントリーを抜粋すると:
この条件にすべて合致しているとログインが転けて↑のエラーを食らう。
試します
挙動をおさらいします。
サーバ側で FLUSH PRIVILEGES を実行しSHA2キャッシュをクリアしたあと、SSLを無効化して接続します。
確かに、Authentication requires secure connection. とエラーが出て、接続できません。
$ mysql -uuser -h my8.local --ssl-mode=DISABLED ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
次に、--get-server-public-key をつけます。このオプションはサーバの公開鍵を自動でクライアントに持ってくるオプションです。
サーバの公開鍵を使って、パスワードを暗号化し、サーバへ送信し、認証が行われます。
$ mysql -uuser -h my8.local --ssl-mode=DISABLED --get-server-public-key mysql>
一度、接続すれば、SHA2キャッシュが作られるので、以降は--get-server-public-key を指定しなくても接続できるようになります。
$ mysql -uuser -h my8.local --ssl-mode=DISABLED mysql>
運用への影響を考えてみる
(サーバを再起動したりして) SHA2キャッシュがクリアされたときに、SSLを利用していないクライアントが一斉に接続エラーになっては困ります。 そのようなことが起こり得るか検討してみます。
mysql コマンド
mysql コマンドはデフォルトでSSLを利用します。あえてSSLを無効化しているようなケースはあまりないでしょう。 コマンドラインでMySQLを使っている場合は、心配しなくて良さそうです。
各種、言語ドライバーはどうでしょうか?
mysql コマンドの --get-server-public-key 相当の挙動がドライバ側に実装されていれば、開発者側では特に意識する必要はないということになりますが。。。
ドライバの挙動
PHP 7.4
PHP 7.4 で試します。
<?php
try {
$pdo = new PDO('mysql:host=my8.local;charset=utf8','user','Password%123');
} catch (PDOException $e) {
exit($e->getMessage());
}
$stmt = $pdo->query("SHOW STATUS LIKE 'Ssl_cipher'");
print_r($stmt->fetch(PDO::FETCH_ASSOC));
おっ、特にエラーなく接続できた!Ssl_cipherが空なのでSSL無効でエラーなく接続できました。
$ php pdo.php
Array
(
[Variable_name] => Ssl_cipher
[Value] =>
)
PHP の コミットログをみると、きちんとサーバ側の公開鍵を自動で取ってくる実装が追加されていそうです👏
https://github.com/php/php-src/commit/d6e81f0bfd0cb90586dd83d4fd47a4302605261a
PHP7.3
PHP 7.3 でも試します。
$ php pdo.php SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
そもそも、caching_sha2_password がサポートされてないようですね 😢
MySQL 8 を使うには PHP7.4 以降を利用する必要があることがわかりました。
node.js
var mysql = require('mysql');
var con = mysql.createConnection({
host: "my8.local",
user: "user",
password: "Password%123"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
// simple query
con.query(
"SHOW STATUS LIKE 'Ssl_cipher'",
function(err, results, fields) {
console.log(results);
}
);
node.js の mysql もまだ caching_sha2_password をサポートしてないようですね。。。。
$ node mysql.js
/home/mita2/nodejs-conn/node_modules/mysql/lib/protocol/Parser.js:437
throw err; // Rethrow non-MySQL errors
^
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
PRは出ているのですが、まだ、取り込まれてないようです。 https://github.com/mysqljs/mysql/pull/2233
mysql2 のほうには取り込まれているようなので、mysql2 を試します。
mysql と mysql2 は互換性があります。ドライバを差し替えるにはvar mysql = require('mysql'); を var mysql = require('mysql2'); にするだけです。
$ node mysql.js
Connected!
[ TextRow { Variable_name: 'Ssl_cipher', Value: '' } ]
大丈夫そうです😄
まとめ
- PHPは 7.4 以上なら大丈夫!
- Node.js のドライバは mysql2 なら大丈夫!