このページは機械翻訳したものです。
MySQL サーバーに接続しようとすると、サーバーは次の条件に基づいて接続を受け入れるか拒否します:
アイデンティティ、および適切な資格証明を指定して検証できるかどうか。
アカウントがロックされているかロック解除されているか。
サーバーはまず資格証明をチェックし、次にアカウントのロック状態をチェックします。 いずれかのステップで障害が発生すると、サーバーはユーザーへのアクセスを完全に拒否します。 それ以外の場合、サーバーは接続を受け入れてステージ 2 に進み、リクエストを待機します。
サーバーは、user
テーブルのカラムを使用してアイデンティティと資格証明のチェックを実行し、次の条件を満たしている場合にのみ接続を受け入れます:
クライアントホスト名およびユーザー名は、一部の
user
テーブルの行のHost
およびUser
のカラムと一致します。Host
およびUser
の許容値を制御するルールについては、セクション6.2.4「アカウント名の指定」 を参照してください。クライアントは、
authentication_string
カラムで示されるように、行で指定された資格証明 (パスワードなど) を提供します。 資格証明は、plugin
カラムで指定された認証プラグインを使用して解釈されます。行は、アカウントがロック解除されていることを示します。 ロック状態は
account_locked
カラムに記録されます。このカラムの値は'N'
である必要があります。 アカウントのロックは、CREATE USER
ステートメントまたはALTER USER
ステートメントを使用して設定または変更できます。
ユーザーの ID は 2 つの部分の情報に基づきます。
MySQL ユーザー名
接続元のクライアントホスト
User
カラム値がブランクでない場合、入接続のユーザー名は正確に一致する必要があります。 User
値がブランクの場合、これはすべてのユーザー名と一致します。 入接続と一致する user
テーブル行のユーザー名がブランクである場合、ユーザーはクライアントが実際に指定した名前を持つユーザーでなく、名前のない匿名ユーザーとみなされます。 つまり、接続期間中の (つまりステージ 2 での) 今後のすべてのアクセスチェックでブランクのユーザー名が使用されることを意味します。
authentication_string
カラムは空白にできます。 これはワイルドカードではなく、あらゆるパスワードが一致するという意味ではありません。 これは、ユーザーはパスワードを指定せずに接続しなければならないことを意味します。 クライアントを認証するプラグインによって実装される認証方法は、authentication_string
カラムのパスワードを使用する場合と使用しない場合があります。 この場合、MySQL サーバーへの認証を行う際に、外部パスワードも使用される可能性があります。
user
テーブルの authentication_string
カラムに格納されている空白以外のパスワード値は暗号化されます。 MySQL では、パスワードはクリアテキストとして格納されず、すべてのユーザーに表示されます。 かわりに、接続しようとしているユーザーが指定したパスワードは暗号化されます (アカウント認証プラグインによって実装されたパスワードハッシュ方式を使用)。 そのあと、暗号化パスワードは、接続プロセス中にパスワードが正しいかどうかをチェックするときに使用されます。 これは、暗号化パスワードが接続を介してやりとりされずに実行されます。 セクション6.2.1「アカウントのユーザー名とパスワード」を参照してください。
MySQL から見ると、暗号化パスワードが実際のパスワードであるため、暗号化パスワードへのアクセス権限をすべてのユーザーに付与しないようにしてください。 特に、「mysql
システムデータベース内のテーブルへの読取りアクセス権を非管理ユーザーに付与しない」です。
次のテーブルに、user
テーブルの User
値と Host
値の様々な組合せが着信接続にどのように適用されるかを示します。
User 値 |
Host 値 |
許容される接続 |
---|---|---|
'fred' |
'h1.example.net' |
fred , h1.example.net からの接続 |
'' |
'h1.example.net' |
h1.example.net から接続する任意のユーザー |
'fred' |
'%' |
任意のホストから接続する fred
|
'' |
'%' |
任意のホストから接続する任意のユーザー |
'fred' |
'%.example.net' |
fred , example.net ドメインの任意のホストからの接続 |
'fred' |
'x.example.%' |
fred 、x.example.net , x.example.com , x.example.edu からの接続など。これはおそらく役に立ちません |
'fred' |
'198.51.100.177' |
IP アドレス 198.51.100.177 のホストから接続する fred
|
'fred' |
'198.51.100.%' |
198.51.100 のクラス C サブネットの任意のホストから接続する fred
|
'fred' |
'198.51.100.0/255.255.255.0' |
前の例と同じ |
入接続のクライアントホスト名およびユーザー名が user
テーブルの複数行と一致することもあります。 前述の一連の例は、これを示しています: 表示されるエントリのいくつかは、fred
による h1.example.net
からの接続と一致します。
複数の一致が可能な場合、サーバーはいずれを使用するかを決定する必要があります。 この問題は、次のように解決されます。
サーバーが
user
テーブルをメモリーに読み取るとき、行を毎回ソートします。クライアントが接続しようとすると、サーバーは行をソート順に参照します。
サーバーは、クライアントホスト名およびユーザー名が一致した最初の行を使用します。
サーバーは、特定の Host
値が最も多い行から順に並べ替えるソートルールを使用します:
リテラル IP アドレスとホスト名は最も具体的です。
-
MySQL 8.0.23 より前は、リテラル IP アドレスの特異性はネットマスクがあるかどうかの影響を受けないため、
198.51.100.13
と198.51.100.0/255.255.255.0
は同等とみなされます。 MySQL 8.0.23 の時点では、ホスト部分に IP アドレスを持つアカウントには次のような特異性があります:-
ホスト部分が IP アドレスとして指定されているアカウント:
CREATE USER 'user_name'@'127.0.0.1'; CREATE USER 'user_name'@'198.51.100.44';
-
CIDR 表記を使用して IP アドレスとして指定されたホスト部分を持つアカウント:
CREATE USER 'user_name'@'192.0.2.21/8'; CREATE USER 'user_name'@'198.51.100.44/16';
-
ホスト部分が IP アドレスとしてサブネットマスクとともに指定されているアカウント:
CREATE USER 'user_name'@'192.0.2.0/255.255.255.0'; CREATE USER 'user_name'@'198.51.0.0/255.255.0.0';
-
パターン
'%'
は「任意のホスト」を意味するため、具体性はもっとも低くなります。空の文字列
''
も「任意のホスト」を意味しますが、'%'
のあとにソートされます。
非 TCP (ソケットファイル、名前付きパイプおよび共有メモリー) 接続は、ローカル接続として扱われ、そのようなアカウントがある場合は localhost
のホスト部分と照合され、そうでない場合は localhost
と一致するワイルドカードを持つホスト部分と照合されます (たとえば、local%
, l%
, %
)。
同じ Host
値を持つ行は、最も固有の User
値から順に並べられます。 空白の User
値は「「任意のユーザー」」を意味し、最も限定的ではないため、同じ Host
値を持つ行の場合、匿名でないユーザーは匿名ユーザーの前にソートされます。
Host
と User
の値が等しい行の場合、順序は非決定的です。
user
テーブルが次の内容であると仮定して、これがどのように作用するかを説明します。
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
サーバーがテーブルをメモリーに読み取るとき、サーバーは前に記載したルールを使用して行をソートします。 ソート後の結果は次のようになります。
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
クライアントが接続しようとすると、サーバーはソート済みの行を参照し、見つかった最初の一致を使用します。 jeffrey
による localhost
からの接続の場合、テーブルの 2 つの行が一致し、すなわち Host
および User
値が 'localhost'
および ''
であるものと、値が '%'
および 'jeffrey'
であるものが一致します。 ソート順では 'localhost'
行が最初になるため、サーバーはこの行を使用します。
次に別の例を示します。 user
テーブルが次のようになっていると仮定します。
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| % | jeffrey | ...
| h1.example.net | | ...
+----------------+----------+-
ソート済みテーブルは次のようになります。
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| h1.example.net | | ...
| % | jeffrey | ...
+----------------+----------+-
最初の行は h1.example.net
の任意のユーザーによる接続と一致し、2 番目の行は任意のホストの jeffrey
による接続と一致します。
よくある誤解として、ある特定のユーザー名についてサーバーが接続に対する一致を検出しようとしたとき、そのユーザーの名前を明示的に指定するすべての行が最初に使用されるという認識があります。 これは正しくありません。 前述の例は、jeffrey
による h1.example.net
からの接続が、User
カラム値として'jeffrey'
を含む行ではなく、ユーザー名のない行によって最初に照合されることを示しています。 その結果、jeffrey
は接続するときにユーザー名を指定したにもかかわらず、匿名ユーザーとして認証されます。
サーバーに接続できても権限が期待したものとは異なる場合、おそらくほかのアカウントとして認証されています。 サーバーがユーザーの認識に使用したアカウントを見つけるには、CURRENT_USER()
関数を使用します。 (セクション12.16「情報関数」を参照してください。) これは、一致する user
テーブル行の User
および Host
値を示す、
形式の値を返します。 たとえば、user_name
@host_name
jeffrey
が接続して、次のクエリーを発行したとします。
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
ここで表示された結果は、一致した user
テーブル行の User
カラム値がブランクであることを示しています。 つまり、サーバーは jeffrey
を匿名ユーザーとして扱っています。
認証の問題を診断するための別の方法は、user
テーブルを出力し、テーブルを手作業でソートして、最初の一致が行われた行を確認する方法です。