Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.1Mb
HTML Download (TGZ) - 10.0Mb
HTML Download (Zip) - 10.1Mb


このページは機械翻訳したものです。

6.2.15 パスワード管理

MySQL は、次のパスワード管理機能をサポートしています:

  • パスワードの有効期限。パスワードを定期的に変更する必要があります。

  • 古いパスワードが再度選択されないようにするためのパスワード再利用の制限。

  • パスワードの検証。パスワードの変更を要求するには、置換する現在のパスワードも指定します。

  • デュアルパスワード。クライアントがプライマリパスワードまたはセカンダリパスワードを使用して接続できるようにします。

  • 強力なパスワードを要求するためのパスワード強度評価。

  • ランダムパスワード生成。明示的な管理者指定のリテラルパスワードを要求するかわりに使用します。

  • パスワードの失敗を追跡して、連続するパスワードログインの失敗が多すぎる場合に一時アカウントロックを有効にします。

次の各セクションでは、validate_password コンポーネントを使用して実装され、セクション6.4.3「パスワード検証コンポーネント」 で説明されているパスワード強度評価を除き、これらの機能について説明します。

重要

MySQL は、mysql システムデータベースのテーブルを使用してパスワード管理機能を実装します。 MySQL を以前のバージョンからアップグレードする場合、システムテーブルが最新でない可能性があります。 その場合、サーバーは起動プロセス中に次のようなメッセージをエラーログに書き込みます (正確な数値は異なる場合があります):

[ERROR] Column count of mysql.user is wrong. Expected
49, found 47. The table is probably corrupted
[Warning] ACL table mysql.password_history missing.
Some operations may fail.

この問題を修正するには、MySQL のアップグレード手順を実行します。 セクション2.11「MySQL のアップグレード」を参照してください。 これが完了するまで、パスワードは変更できませんは次のようになります。

内部資格証明記憶域と外部資格証明記憶域

一部の認証プラグインでは、アカウント資格証明が mysql.user システムテーブルの MySQL に内部的に格納されます:

  • mysql_native_password

  • caching_sha2_password

  • sha256_password

ここで説明するほとんどのパスワード管理機能は、MySQL 自体で処理される内部資格証明記憶域に基づいているため、このセクションのほとんどの説明はこのような認証プラグインに適用されます。 その他の認証プラグインは、MySQL の外部にアカウント資格証明を格納します。 外部資格証明システムに対して認証を実行するプラグインを使用するアカウントの場合、パスワード管理もそのシステムに対して外部で処理する必要があります。

例外は、内部資格証明記憶域を使用するアカウントのみでなく、失敗したログイン追跡および一時アカウントロックのオプションがすべてのアカウントに適用されることです。これは、MySQL では、内部資格証明記憶域を使用するか外部資格証明記憶域を使用するかに関係なく、任意のアカウントのログイン試行のステータスを評価できるためです。

個々の認証プラグインの詳細は、セクション6.4.1「認証プラグイン」 を参照してください。

パスワード有効期限ポリシー

MySQL を使用すると、データベース管理者はアカウントパスワードを手動で期限切れにしたり、自動パスワード期限切れのポリシーを設定できます。 有効期限ポリシーはグローバルに設定でき、個々のアカウントは、グローバルポリシーに従うか、特定のアカウントごとの動作でグローバルポリシーをオーバーライドするように設定できます。

アカウントパスワードを手動で期限切れにするには、ALTER USER ステートメントを使用します:

ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;

この操作は、mysql.user システムテーブルの対応する行でパスワードを期限切れとマークします。

ポリシーに従ったパスワードの有効期限は自動的に設定され、特定のアカウントのパスワード有効期限は、最新のパスワード変更の日時から評価されます。 mysql.user システムテーブルには、各アカウントのパスワードが最後に変更された時間が示され、その有効期間が許容される存続期間を超えると、サーバーはクライアント接続時にパスワードを期限切れとして自動的に処理します。 これは、明示的な手動パスワード有効期限なしで機能します。

自動パスワード失効ポリシーをグローバルに確立するには、default_password_lifetime システム変数を使用します。 デフォルト値は 0 で、自動パスワード有効期限は無効になります。 default_password_lifetime の値が正の整数の N である場合、パスワードを N 日ごとに変更する必要があるように、許可されたパスワードの存続期間を示します。

例:

  • パスワードの存続期間が約 6 か月であるグローバルポリシーを確立するには、サーバー my.cnf ファイルで次の行を使用してサーバーを起動します:

    [mysqld]
    default_password_lifetime=180
  • パスワードが期限切れにならないようにグローバルポリシーを設定するには、default_password_lifetime を 0 に設定します:

    [mysqld]
    default_password_lifetime=0
  • default_password_lifetime は、実行時に設定および永続化することもできます:

    SET PERSIST default_password_lifetime = 180;
    SET PERSIST default_password_lifetime = 0;

    SET PERSIST は、実行中の MySQL インスタンスの値を設定します。 また、後続のサーバー再起動に引き継ぐための値も保存されます。セクション13.7.6.1「変数代入の SET 構文」 を参照してください。 後続の再起動に引き継ぐことなく、実行中の MySQL インスタンスの値を変更するには、PERSIST ではなく GLOBAL キーワードを使用します。

グローバルパスワード失効ポリシーは、オーバーライドするように設定されていないすべてのアカウントに適用されます。 個々のアカウントのポリシーを設定するには、CREATE USER および ALTER USER ステートメントの PASSWORD EXPIRE オプションを使用します。 セクション13.7.1.3「CREATE USER ステートメント」およびセクション13.7.1.1「ALTER USER ステートメント」を参照してください。

アカウント固有のステートメントの例:

  • 90 日ごとにパスワードを変更する必要があります:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

    この有効期限オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • パスワードの有効期限の無効化:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;

    この有効期限オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • ステートメントで指定されたすべてのアカウントのグローバルな有効期限ポリシーに従います:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;

クライアントが正常に接続すると、サーバーはアカウントパスワードの有効期限が切れているかどうかを判断します:

  • サーバーは、パスワードが手動で期限切れになっているかどうかを確認します。

  • それ以外の場合、サーバーは、自動パスワード有効期限ポリシーに従って、パスワードの有効期間が許可された存続期間を超えているかどうかを確認します。 その場合、サーバーはパスワードの有効期限が切れたとみなします。

パスワードの有効期限が切れた場合 (手動か自動かに関係なく)、サーバーはクライアントを切断するか、許可されている操作を制限します (セクション6.2.16「期限切れパスワードのサーバー処理」 を参照)。 制限付きクライアントによって実行される操作は、ユーザーが新しいアカウントパスワードを確立するまでエラーになります:

mysql> SELECT 1;
ERROR 1820 (HY000): You must reset your password using ALTER USER
statement before executing this statement.

mysql> ALTER USER USER() IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

クライアントがパスワードをリセットすると、サーバーはセッションの通常のアクセスと、そのアカウントを使用する後続の接続をリストアします。 管理ユーザーがアカウントパスワードをリセットすることもできますが、そのアカウントの既存の制限付きセッションは制限されたままになります。 アカウントを使用するクライアントは、ステートメントを正常に実行する前に切断して再接続する必要があります。

注記

期限切れのパスワードは、現在の値に設定することで reset で使用できますが、適切なポリシーとして、別のパスワードを選択することをお薦めします。 DBA は、適切なパスワード再利用ポリシーを確立することで、非キューを強制できます。 パスワード再利用ポリシーを参照してください。

パスワード再利用ポリシー

MySQL では、以前のパスワードの再利用に制限を適用できます。 再利用制限は、パスワード変更の数、経過時間、またはその両方に基づいて設定できます。 再利用ポリシーはグローバルに確立でき、個々のアカウントはグローバルポリシーに従うように設定することも、特定のアカウントごとの動作でグローバルポリシーをオーバーライドするように設定することもできます。

アカウントのパスワード履歴は、過去に割り当てられたパスワードで構成されます。 MySQL では、新しいパスワードがこの履歴から選択されないように制限できます:

  • アカウントがパスワード変更数に基づいて制限されている場合、指定された数の最新のパスワードから新しいパスワードを選択することはできません。 たとえば、パスワード変更の最小数が 3 に設定されている場合、新しいパスワードは最新の 3 つのパスワードと同じにできません。

  • 経過時間に基づいてアカウントが制限されている場合、履歴内の指定した日数より新しいパスワードから新しいパスワードを選択することはできません。 たとえば、パスワードの再利用間隔が 60 に設定されている場合、新しいパスワードは過去 60 日以内に選択されたパスワードの中にあってはなりません。

注記

空のパスワードはパスワード履歴にカウントされず、いつでも再利用される可能性があります。

パスワード再利用ポリシーをグローバルに確立するには、password_history および password_reuse_interval システム変数を使用します。

例:

  • 365 日より新しい過去 6 つのパスワードまたはパスワードの再利用を禁止するには、サーバーの my.cnf ファイルに次の行を挿入します:

    [mysqld]
    password_history=6
    password_reuse_interval=365
  • 実行時に変数を設定して永続化するには、次のようなステートメントを使用します:

    SET PERSIST password_history = 6;
    SET PERSIST password_reuse_interval = 365;

    SET PERSIST は、実行中の MySQL インスタンスの値を設定します。 また、後続のサーバー再起動に引き継ぐための値も保存されます。セクション13.7.6.1「変数代入の SET 構文」 を参照してください。 後続の再起動に引き継ぐことなく、実行中の MySQL インスタンスの値を変更するには、PERSIST ではなく GLOBAL キーワードを使用します。

グローバルパスワード再利用ポリシーは、オーバーライドするように設定されていないすべてのアカウントに適用されます。 個々のアカウントのポリシーを設定するには、CREATE USER および ALTER USER ステートメントの PASSWORD HISTORY および PASSWORD REUSE INTERVAL オプションを使用します。 セクション13.7.1.3「CREATE USER ステートメント」およびセクション13.7.1.1「ALTER USER ステートメント」を参照してください。

アカウント固有のステートメントの例:

  • 再利用を許可する前に、少なくとも 5 つのパスワード変更が必要です:

    CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;
    ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;

    この履歴長オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • 再利用を許可する前に 365 日以上経過する必要があります:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;

    この time-elapsed オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • 両方のタイプの再利用制限を組み合せるには、PASSWORD HISTORYPASSWORD REUSE INTERVAL を組み合せて使用します:

    CREATE USER 'jeffrey'@'localhost'
      PASSWORD HISTORY 5
      PASSWORD REUSE INTERVAL 365 DAY;
    ALTER USER 'jeffrey'@'localhost'
      PASSWORD HISTORY 5
      PASSWORD REUSE INTERVAL 365 DAY;

    これらのオプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシー再利用制限をオーバーライドします。

  • 両方のタイプの再利用制限について、グローバルポリシーに従います:

    CREATE USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;
    ALTER USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;

パスワード検証必須ポリシー

MySQL 8.0.13 の時点では、置換する現在のパスワードを指定して、アカウントパスワードの変更の試行を検証する必要があります。 これにより、DBA は、現在のパスワードを知らなくてもユーザーがパスワードを変更できないようにできます。 このような変更は、たとえば、あるユーザーがログアウトせずに一時的に端末セッションから離れると、悪質なユーザーが元のユーザー MySQL パスワードを変更するためにセッションを使用した場合に発生する可能性があります。 これには、次のような不適切な結果が生じる可能性があります:

  • 管理者がアカウントパスワードをリセットするまで、元のユーザーは MySQL にアクセスできなくなります。

  • パスワードのリセットが発生するまで、悪質なユーザーは無害なユーザー変更の資格証明を使用して MySQL にアクセスできます。

パスワード検証ポリシーはグローバルに確立でき、個々のアカウントは、グローバルポリシーに従うか、特定のアカウントごとの動作でグローバルポリシーをオーバーライドするように設定できます。

アカウントごとに、その mysql.user 行は、パスワード変更試行のために現在のパスワードの検証を必要とするアカウント固有の設定があるかどうかを示します。 この設定は、CREATE USER および ALTER USER ステートメントの PASSWORD REQUIRE オプションによって確立されます:

  • アカウント設定が PASSWORD REQUIRE CURRENT の場合、パスワード変更では現在のパスワードを指定する必要があります。

  • アカウント設定が PASSWORD REQUIRE CURRENT OPTIONAL の場合、パスワードの変更では現在のパスワードを指定する必要はありません。

  • アカウント設定が PASSWORD REQUIRE CURRENT DEFAULT の場合、password_require_current システム変数によってアカウントの検証必須ポリシーが決定されます:

    • password_require_current が有効な場合、パスワード変更では現在のパスワードを指定する必要があります。

    • password_require_current が無効になっている場合、パスワードの変更では現在のパスワードを指定する必要はありません。

つまり、アカウント設定が PASSWORD REQUIRE CURRENT DEFAULT でない場合、アカウント設定は password_require_current システム変数によって設定されたグローバルポリシーよりも優先されます。 それ以外の場合、アカウントは password_require_current 設定に従います。

デフォルトでは、パスワード検証はオプションです: password_require_current が無効になり、PASSWORD REQUIRE オプションなしで作成されたアカウントは PASSWORD REQUIRE CURRENT DEFAULT にデフォルト設定されます。

次のテーブルは、アカウントごとの設定が password_require_current システム変数値とどのように相互作用して、アカウントパスワードの検証が必要なポリシーを決定するかを示しています。

表 6.10 パスワード検証ポリシー

アカウントごとの設定 password_require_current システム変数 パスワードの変更には現在のパスワードが必要ですか。
PASSWORD REQUIRE CURRENT OFF はい
PASSWORD REQUIRE CURRENT ON はい
PASSWORD REQUIRE CURRENT OPTIONAL OFF いいえ
PASSWORD REQUIRE CURRENT OPTIONAL ON いいえ
PASSWORD REQUIRE CURRENT DEFAULT OFF いいえ
PASSWORD REQUIRE CURRENT DEFAULT ON はい

注記

特権ユーザーは、検証必須ポリシーに関係なく、現在のパスワードを指定せずに任意のアカウントパスワードを変更できます。 特権ユーザーは、mysql システムデータベースに対するグローバル CREATE USER 権限または UPDATE 権限を持つユーザーです。

パスワード検証ポリシーをグローバルに確立するには、password_require_current システム変数を使用します。 デフォルト値は OFF であるため、アカウントパスワードの変更で現在のパスワードを指定する必要はありません。

例:

  • パスワード変更で現在のパスワードを指定する必要があるグローバルポリシーを確立するには、サーバー my.cnf ファイルで次の行を使用してサーバーを起動します:

    [mysqld]
    password_require_current=ON
  • 実行時に password_require_current を設定および永続化するには、次のいずれかのステートメントを使用します:

    SET PERSIST password_require_current = ON;
    SET PERSIST password_require_current = OFF;

    SET PERSIST は、実行中の MySQL インスタンスの値を設定します。 また、後続のサーバー再起動に引き継ぐための値も保存されます。セクション13.7.6.1「変数代入の SET 構文」 を参照してください。 後続の再起動に引き継ぐことなく、実行中の MySQL インスタンスの値を変更するには、PERSIST ではなく GLOBAL キーワードを使用します。

グローバルパスワード検証必須ポリシーは、オーバーライドするように設定されていないすべてのアカウントに適用されます。 個々のアカウントのポリシーを設定するには、CREATE USER および ALTER USER ステートメントの PASSWORD REQUIRE オプションを使用します。 セクション13.7.1.3「CREATE USER ステートメント」およびセクション13.7.1.1「ALTER USER ステートメント」を参照してください。

アカウント固有のステートメントの例:

  • パスワードの変更で現在のパスワードを指定する必要があります:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;

    この検証オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • パスワードの変更で現在のパスワードを指定する必要はありません (現在のパスワードを指定する必要はあります):

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;

    この検証オプションは、ステートメントで指定されたすべてのアカウントのグローバルポリシーをオーバーライドします。

  • ステートメントで指定されたすべてのアカウントのグローバルパスワード検証必須ポリシーに従います:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;

ユーザーが ALTER USER または SET PASSWORD ステートメントを使用してパスワードを変更すると、現在のパスワードの検証が行われます。 この例では、SET PASSWORD よりも優先される ALTER USER を使用していますが、ここで説明する原則は両方のステートメントで同じです。

password-change ステートメントでは、置換する現在のパスワードを REPLACE 句で指定します。 例:

  • 現在のユーザーパスワードを変更します:

    ALTER USER USER() IDENTIFIED BY 'auth_string' REPLACE 'current_auth_string';
  • 名前付きユーザーのパスワードを変更します:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED BY 'auth_string'
      REPLACE 'current_auth_string';
  • 名前付きユーザー認証プラグインおよびパスワードを変更します:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED WITH caching_sha2_password BY 'auth_string'
      REPLACE 'current_auth_string';

REPLACE 句は次のように機能します:

  • 現在のパスワードを指定するためにアカウントのパスワード変更が必要な場合は、変更しようとしているユーザーが実際に現在のパスワードを知っていることを確認するために、REPLACE を指定する必要があります。

  • アカウントのパスワード変更で現在のパスワードを指定する必要がない場合、REPLACE はオプションです。

  • REPLACE が指定されている場合は、正しい現在のパスワードを指定する必要があります。そうしないと、エラーが発生します。 これは、REPLACE がオプションの場合でも当てはまります。

  • REPLACE は、現在のユーザーのアカウントパスワードを変更する場合にのみ指定できます。 (つまり、前述の例では、現在のユーザーが jeffrey でないかぎり、jeffrey のアカウントを明示的に指定するステートメントは失敗します。) これは、特権ユーザーが別のユーザーに対して変更を試みた場合でも当てはまりますが、そのようなユーザーは REPLACE を指定せずに任意のパスワードを変更できます。

  • クリアテキストパスワードが書き込まれないように、バイナリログから REPLACE が省略されています。

デュアルパスワードのサポート

MySQL 8.0.14 の時点では、ユーザーアカウントは、プライマリパスワードおよびセカンダリパスワードとして指定されたデュアルパスワードを持つことができます。 デュアルパスワード機能により、次のようなシナリオで資格証明の変更をシームレスに実行できます:

  • システムには多数の MySQL サーバーがあり、レプリケーションが含まれる可能性があります。

  • 複数のアプリケーションが異なる MySQL サーバーに接続します。

  • 定期的な資格証明の変更は、アプリケーションがサーバーに接続するために使用するアカウントに対して行う必要があります。

アカウントが単一のパスワードのみを許可されている場合に、前述のタイプのシナリオで資格証明の変更を実行する方法を検討してください。 この場合、アカウントパスワードが変更されてすべてのサーバーに伝播されるタイミング、およびアカウントを使用するすべてのアプリケーションが新しいパスワードを使用するように更新されるタイミングには、緊密な連携が必要です。 このプロセスには、サーバーまたはアプリケーションを使用できない停止時間が含まれる場合があります。

デュアルパスワードを使用すると、資格証明の変更をフェーズでより簡単に行うことができ、密接な連携や停止時間なしで行うことができます:

  1. 影響を受けるアカウントごとに、現在のパスワードをセカンダリパスワードとして保持して、サーバーに新しいプライマリパスワードを設定します。 これにより、サーバーは各アカウントのプライマリパスワードまたはセカンダリパスワードを認識できますが、アプリケーションは以前と同じパスワード (現在はセカンダリパスワード) を使用して引き続きサーバーに接続できます。

  2. パスワード変更がすべてのサーバーに伝播されたら、影響を受けるアカウントを使用するアプリケーションを変更し、アカウントプライマリパスワードを使用して接続します。

  3. すべてのアプリケーションがセカンダリパスワードからプライマリパスワードに移行されると、セカンダリパスワードは不要になり、破棄できます。 この変更がすべてのサーバーに伝播された後は、各アカウントのプライマリパスワードのみを使用して接続できます。 資格証明の変更が完了しました。

MySQL には、セカンダリパスワードを保存および破棄する構文を使用したデュアルパスワード機能が実装されています:

  • ALTER USER および SET PASSWORD ステートメントの RETAIN CURRENT PASSWORD 句では、新しいプライマリパスワードを割り当てるときに、アカウントの現在のパスワードがセカンダリパスワードとして保存されます。

  • ALTER USERDISCARD OLD PASSWORD 句では、アカウントセカンダリパスワードが破棄され、プライマリパスワードのみが残されます。

前述の資格証明変更シナリオでは、アプリケーションがサーバーに接続するために'appuser1'@'host1.example.com'という名前のアカウントを使用し、アカウントパスワードを'password_a'から'password_b'に変更するとします。

この資格証明の変更を実行するには、次のように ALTER USER を使用します:

  1. レプリカではない各サーバーで、'password_b'を新しい appuser1 プライマリパスワードとして確立し、現在のパスワードをセカンダリパスワードとして保持します:

    ALTER USER 'appuser1'@'host1.example.com'
      IDENTIFIED BY 'password_b'
      RETAIN CURRENT PASSWORD;
  2. パスワード変更がシステム全体ですべてのレプリカにレプリケートされるのを待ちます。

  3. 'password_a'ではなく'password_b'のパスワードを使用してサーバーに接続するように、appuser1 アカウントを使用する各アプリケーションを変更します。

  4. この時点で、セカンダリパスワードは不要になりました。 レプリカではない各サーバーで、セカンダリパスワードを破棄します:

    ALTER USER 'appuser1'@'host1.example.com'
      DISCARD OLD PASSWORD;
  5. 廃棄パスワードの変更がすべてのレプリカにレプリケートされると、資格証明の変更が完了します。

RETAIN CURRENT PASSWORD 句および DISCARD OLD PASSWORD 句には、次の効果があります:

  • RETAIN CURRENT PASSWORD は、アカウントの現在のパスワードをセカンダリパスワードとして保持し、既存のセカンダリパスワードを置き換えます。 新しいパスワードはプライマリパスワードになりますが、クライアントはアカウントを使用して、プライマリパスワードまたはセカンダリパスワードのいずれかを使用してサーバーに接続できます。 (例外: ALTER USER ステートメントまたは SET PASSWORD ステートメントで指定された新しいパスワードが空の場合、RETAIN CURRENT PASSWORD が指定されていてもセカンダリパスワードも空になります。)

  • プライマリパスワードが空のアカウントに RETAIN CURRENT PASSWORD を指定すると、ステートメントは失敗します。

  • アカウントにセカンダリパスワードがあり、RETAIN CURRENT PASSWORD を指定せずにプライマリパスワードを変更した場合、セカンダリパスワードは変更されません。

  • ALTER USER の場合、アカウントに割り当てられた認証プラグインを変更すると、セカンダリパスワードは破棄されます。 認証プラグインを変更し、RETAIN CURRENT PASSWORD も指定すると、ステートメントは失敗します。

  • ALTER USER では、セカンダリパスワードが存在する場合、DISCARD OLD PASSWORD は破棄します。 アカウントはプライマリパスワードのみを保持し、クライアントはプライマリパスワードのみを使用してサーバーに接続するためにアカウントを使用できます。

セカンダリパスワードを変更するステートメントには、次の権限が必要です:

  • 自分のアカウントに適用される ALTER USER および SET PASSWORD ステートメントに RETAIN CURRENT PASSWORD または DISCARD OLD PASSWORD 句を使用するには、APPLICATION_PASSWORD_ADMIN 権限が必要です。 ほとんどのユーザーは 1 つのパスワードのみを必要とするため、自分のセカンダリパスワードを操作するには権限が必要です。

  • アカウントがすべてのアカウントのセカンダリパスワードの操作を許可される場合は、APPLICATION_PASSWORD_ADMIN ではなく CREATE USER 権限を付与する必要があります。

ランダムパスワード生成

MySQL 8.0.18 では、CREATE USERALTER USER および SET PASSWORD ステートメントに、明示的に管理者指定のリテラルパスワードを要求するかわりに、ユーザーアカウントのランダムパスワードを生成する機能があります。 構文の詳細は、各ステートメントの説明を参照してください。 このセクションでは、生成されるランダムパスワードに共通する特性について説明します。

デフォルトでは、生成されるランダムパスワードの長さは 20 文字です。 この長さは、5 から 255 の範囲の generated_random_password_length システム変数によって制御されます。

ステートメントがランダムなパスワードを生成するアカウントごとに、このステートメントは、アカウント認証プラグイン用に適切にハッシュされたパスワードを mysql.user システムテーブルに格納します。 このステートメントは、ステートメントを実行するユーザーまたはアプリケーションが使用できるように、結果セットの行にクリアテキストのパスワードも返します。 結果セットカラムの名前は userhost および generated password で、mysql.user システムテーブルの影響を受ける行を識別するユーザー名とホスト名の値、およびクリアテキストで生成されたパスワードを示します。

mysql> CREATE USER
       'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
       'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD,
       'u3'@'%.org' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+
| user | host          | generated password   |
+------+---------------+----------------------+
| u1   | localhost     | BA;42VpXqQ@i+y{&TDFF |
| u2   | %.example.com | YX5>XRAJRP@>sn9azmD4 |
| u3   | %.org         | ;GfD44l,)C}PI/6)4TwZ |
+------+---------------+----------------------+
mysql> ALTER USER
       'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
       'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+
| user | host          | generated password   |
+------+---------------+----------------------+
| u1   | localhost     | yhXBrBp.;Y6abB)e_UWr |
| u2   | %.example.com | >M-vmjp9DTY6}hkp,RcC |
+------+---------------+----------------------+
mysql> SET PASSWORD FOR 'u3'@'%.org' TO RANDOM;
+------+-------+----------------------+
| user | host  | generated password   |
+------+-------+----------------------+
| u3   | %.org | o(._oNn)d;FC<vJIDg9M |
+------+-------+----------------------+

アカウントのランダムパスワードを生成する CREATE USERALTER USER または SET PASSWORD ステートメントは、IDENTIFIED WITH auth_plugin AS 'auth_string'句を含む CREATE USER または ALTER USER ステートメントとしてバイナリログに書き込まれます。auth_plugin はアカウント認証プラグインで、'auth_string'はアカウントのハッシュパスワード値です。

validate_password コンポーネントがインストールされている場合、実装されているポリシーは生成されたパスワードに影響しません。 (パスワード検証の目的は、人間がより適切なパスワードを作成できるようにすることです。)

失敗したログイントラッキングと一時アカウントロック

MySQL 8.0.19 の時点では、管理者は、連続するログイン失敗が多すぎると一時アカウントロックが発生するようにユーザーアカウントを構成できます。

このコンテキストの「ログイン失敗」は、接続試行中にクライアントが正しいパスワードを指定できないことを意味します。 不明なユーザーまたはネットワークの問題などの理由で接続に失敗することは含まれません。 デュアルパスワードを持つアカウント (デュアルパスワードのサポート を参照) の場合、どちらのアカウントパスワードも正しいものとしてカウントされます。

必要なログイン失敗の数とロック時間は、CREATE USER および ALTER USER ステートメントの FAILED_LOGIN_ATTEMPTS および PASSWORD_LOCK_TIME オプションを使用してアカウントごとに構成できます。 例:

CREATE USER 'u1'@'localhost' IDENTIFIED BY 'password'
  FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;

ALTER USER 'u2'@'localhost'
  FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;

連続したログイン失敗が多すぎる場合、クライアントは次のようなエラーを受け取ります:

ERROR 3957 (HY000): Access denied for user user.
Account is blocked for D day(s) (R day(s) remaining)
due to N consecutive failed logins.

次のオプションを使用します:

  • FAILED_LOGIN_ATTEMPTS N

    このオプションは、不正なパスワードを指定するアカウントログイン試行を追跡するかどうかを示します。 N の数には、一時的なアカウントロックを引き起こす連続した不正なパスワードの数を指定します。

  • PASSWORD_LOCK_TIME {N | UNBOUNDED}

    このオプションは、連続して何回もログインしようとすると間違ったパスワードが提供された後に、アカウントをロックする期間を示します。 値は、アカウントがロックされたままになる日数を指定する N の数値、またはアカウントが一時的にロックされた状態になるとその状態の期間が無制限になり、アカウントがロック解除されるまで終了しないことを指定する UNBOUNDED です。 ロック解除が行われる条件については、後で説明します。

各オプションに許可される N の値は、0 から 32767 の範囲です。 値 0 を指定すると、オプションが無効になります。

ログイン失敗トラッキングと一時アカウントロックには、次の特性があります:

  • 失敗したログイン追跡および一時ロックをアカウントに対して実行するには、その FAILED_LOGIN_ATTEMPTS オプションと PASSWORD_LOCK_TIME オプションの両方をゼロ以外にする必要があります。

  • CREATE USER では、FAILED_LOGIN_ATTEMPTS または PASSWORD_LOCK_TIME が指定されていない場合、ステートメントで指定されたすべてのアカウントの暗黙的なデフォルト値は 0 です。 これは、失敗したログイントラッキングおよび一時アカウントロックが無効であることを意味します。 (これらの暗黙的なデフォルトは、失敗したログイン追跡の導入前に作成されたアカウントにも適用されます。)

  • ALTER USER では、FAILED_LOGIN_ATTEMPTS または PASSWORD_LOCK_TIME が指定されていない場合、ステートメントで指定されたすべてのアカウントの値は変更されません。

  • 一時アカウントロックを実行するには、パスワード障害が連続して発生する必要があります。 失敗したログインの FAILED_LOGIN_ATTEMPTS 値に達する前に正常にログインすると、失敗カウントがリセットされます。 たとえば、FAILED_LOGIN_ATTEMPTS が 4 で、3 つの連続したパスワード障害が発生した場合、ロックを開始するにはさらに障害が発生する必要があります。 ただし、次回のログインが成功した場合は、ロックに 4 つの連続した失敗が再度必要になるように、アカウントの失敗ログインカウントがリセットされます。

  • 一時ロックが開始されると、ロック期間が経過するか、次の説明に示す account-reset メソッドのいずれかによってアカウントのロックが解除されるまで、正しいパスワードを使用してもログインは成功しません。

サーバーは、付与テーブルを読み取るときに、失敗したログイン追跡が有効かどうか、現在アカウントが一時的にロックされているかどうか、ロックが開始された場合はロックが開始された場合、およびアカウントがロックされていない場合に一時的なロックが発生するまでの失敗数に関する状態情報をアカウントごとに初期化します。

アカウント状態情報をリセットできます。つまり、失敗したログイン数がリセットされ、アカウントが現在一時的にロックされている場合はロック解除されます。 アカウントのリセットは、すべてのアカウントに対してグローバルにすることも、アカウントごとに行うこともできます:

  • すべてのアカウントのグローバルリセットは、次のいずれかの状況で発生します:

    • サーバーの再起動。

    • FLUSH PRIVILEGES の実行。 (--skip-grant-tables を使用してサーバーを起動すると、付与テーブルが読み取られず、失敗したログイン追跡が無効になります。 この場合、FLUSH PRIVILEGES を最初に実行すると、すべてのアカウントのリセットに加えて、サーバーが付与テーブルを読み取り、失敗したログイン追跡を有効にします。)

  • アカウントごとのリセットは、次のいずれかの状況で発生します:

    • アカウントのログインに成功しました。

    • ロック期間が経過します。 この場合、ログイン失敗回数は次回のログイン試行時にリセットされます。

    • FAILED_LOGIN_ATTEMPTS または PASSWORD_LOCK_TIME (あるいはその両方) を任意の値 (現在のオプション値を含む) に設定するアカウントに対する ALTER USER ステートメントの実行、またはアカウントに対する ALTER USER ... UNLOCK ステートメントの実行。

      アカウントの他の ALTER USER ステートメントは、現在の失敗ログイン数またはロック状態には影響しません。

失敗したログイントラッキングは、資格証明のチェックに使用されるログインアカウントに関連付けられます。 ユーザープロキシが使用されている場合、プロキシユーザーではなくプロキシユーザーに対してトラッキングが行われます。 つまり、トラッキングは、CURRENT_USER() で示されるアカウントではなく、USER() で示されるアカウントに関連付けられます。 プロキシユーザーとプロキシユーザーの区別の詳細は、セクション6.2.18「プロキシユーザー」 を参照してください。