mita2 database life

主にMySQLに関するメモです

MySQL Go のドライバ と caching_sha2_password

mysql_native_password の廃止が近づいてきた...

MySQL 8.4 では mysql_native_password がデフォルトで無効化されてしまいました。 そろそろ、mysql_native_password 方式の利用の撲滅に本気にならないといけないようです。

sakaik.hateblo.jp

mysql_native_password 方式 から、よりセキュアな caching_sha2_password 方式に変更することになります。 認証まわりの変更には接続ドライバの対応も必要。Goのドライバの対応状況や挙動を確認しました。

caching_sha2_password に 対応しているバージョン

結論から言うと、go-sql-driver/mysqlVersion 1.4.1 (2018-11-14 リリース) *1 以降を利用していれば、問題なし。 特にコードの変更も必要なし。なお、SSL接続ではなく、平文接続で検証しています (MySQL 8.0のcaching_sha2_password + 非SSL接続が転ける が発生しないかの確認)。

念の為、サーバ側 の default_authentication_plugin 設定が mysql_native_password, caching_sha2_password の 2パターン、実際のユーザのパスワードが mysql_native_password, caching_sha2_password の2パターン、の組み合わせ、合計4パターンをテストしました。 いずれのパターンでも、 1.4.1 以降であれば問題なく接続できました。


なお、v1.3 だと、caching_sha2_password を使ったユーザに接続しようとすると以下のエラーになる。

$ ./main  app
panic: this authentication plugin is not supported

default_authentication_plugin と Auth Switch Request

go-sql-driver/mysql では、クライアントは サーバ側default_authentication_plugin 設定に指定された認証方式で認証をまず試みる。 そして、実際のユーザの認証方法(Authentication plugin (sha2 or native)) が異なっていた場合、サーバは改めて、正しい方式で認証しなおすようクライアントにリクエストします。

以下のパケットキャプチャで「Auth Switch Request」となっている部分

packetcapture

caching_sha2_password への切り替え過程では、default_authentication_plugin と ユーザの Authentication plugin が異なる期間が発生してしまう。 この期間は接続処理がAuth Switch Requestぶん、1往復増えるので、コネクションプーリングをしていないレイテンシのある環境では注意が必要かもしれない。

あと、caching_sha2_password への切り替えが終わったら、default_authentication_pluginも(もし、mysql_native_password に変更していたら)caching_sha2_passwordに忘れずに変更したい。 そうしないと、1往復無駄が発生し続ける。

このあたりはドライバによって挙動が異なる模様。以下のページで詳しく解説されています。

dev.mysql.com

mysql_native_password を使い続けたい場合

古いドライバを使っていて、mysql_native_password を使い続けたい場合、default_authentication_pluginmysql_native_password に変更したほうが良い。 古いドライバでは、ユーザのパスワードが mysql_native_password だったとしても、default_authentication_plugincaching_sha2_password というだけでエラーになってしまうパターンが存在した(以下の表のNo.7)。

まとめの表

matrix

*1: caching_sha2_password は v1.4.0 で入ったが、v1.4.1 でバグが修正されている