ユーザーが MySQL サーバーに接続しようとすると、サーバーはユーザーの ID と、正しいパスワードを指定することでユーザーが自分の ID を検証できるかどうかに基づいて、接続を受け入れるか拒否します。できない場合、サーバーはアクセスを完全に拒否します。それ以外の場合、サーバーは接続を受け入れてステージ 2 に進み、リクエストを待機します。
ユーザーの ID は 2 つの部分の情報に基づきます。
接続元のクライアントホスト
MySQL ユーザー名
ID チェックは、user
テーブルの 3 つのスコープカラム (Host
、User
、Password
) を使用して実施されます。サーバーは、一部の user
テーブル行の Host
および User
カラムがクライアントホスト名およびユーザー名と一致し、その行に指定されているパスワードがクライアントから提供された場合のみ、接続を受け入れます。許容可能な Host
および User
値についてのルールは、セクション6.2.3「アカウント名の指定」にあります。
User
カラム値がブランクでない場合、入接続のユーザー名は正確に一致する必要があります。User
値がブランクの場合、これはすべてのユーザー名と一致します。入接続と一致する user
テーブル行のユーザー名がブランクである場合、ユーザーはクライアントが実際に指定した名前を持つユーザーでなく、名前のない匿名ユーザーとみなされます。つまり、接続期間中の (つまりステージ 2 での) 今後のすべてのアクセスチェックでブランクのユーザー名が使用されることを意味します。
Password
カラムはブランクにできます。これはワイルドカードではなく、あらゆるパスワードが一致するという意味ではありません。これは、ユーザーはパスワードを指定せずに接続しなければならないことを意味します。サーバーがプラグインを使用してクライアントを認証する場合、プラグインが実装する認証方式で、Password
カラムのパスワードが使用される場合もそうでない場合もあります。この場合、MySQL サーバーへの認証を行う際に、外部パスワードも使用される可能性があります。
user
テーブル内のブランクでない Password
値は暗号化パスワードを表します。MySQL は、すべてのユーザーが表示できるプレーンテキスト形式のパスワードを格納しません。代わりに、接続しようとしたユーザーが入力したパスワードは (PASSWORD()
関数を使用して) 暗号化されます。そのあと、暗号化パスワードは、接続プロセス中にパスワードが正しいかどうかをチェックするときに使用されます。これは、暗号化パスワードが接続を介してやりとりされずに実行されます。セクション6.3.1「ユーザー名とパスワード」を参照してください。
MySQL から見ると、暗号化パスワードが実際のパスワードであるため、暗号化パスワードへのアクセス権限をすべてのユーザーに付与しないようにしてください。特に、管理者以外のユーザーに、mysql
データベース内のテーブルへの読み取りアクセス権限を付与しないでください。
次の表では、user
テーブルエントリの Host
値および User
値のさまざまな組み合わせが入接続にどのように適用されるかを示しています。
Host 値 |
User 値 |
許容される接続 |
---|---|---|
'thomas.loc.gov' |
'fred' |
thomas.loc.gov から接続する fred
|
'thomas.loc.gov' |
'' |
thomas.loc.gov から接続するすべてのユーザー |
'%' |
'fred' |
任意のホストから接続する fred
|
'%' |
'' |
任意のホストから接続する任意のユーザー |
'%.loc.gov' |
'fred' |
loc.gov ドメイン内の任意のホストから接続する fred
|
'x.y.%' |
'fred' |
x.y.net 、x.y.com 、x.y.edu などから接続する fred 。おそらく有用ではありません |
'144.155.166.177' |
'fred' |
IP アドレス 144.155.166.177 のホストから接続する fred
|
'144.155.166.%' |
'fred' |
144.155.166 のクラス C サブネットの任意のホストから接続する fred
|
'144.155.166.0/255.255.255.0' |
'fred' |
前の例と同じ |
入接続のクライアントホスト名およびユーザー名が user
テーブルの複数行と一致することもあります。このことは前の一連の例で示されており、示されている複数のエントリが、fred
による thomas.loc.gov
からの接続に一致します。
複数の一致が可能な場合、サーバーはいずれを使用するかを決定する必要があります。この問題は、次のように解決されます。
サーバーが
user
テーブルをメモリーに読み取るとき、行を毎回ソートします。クライアントが接続しようとすると、サーバーは行をソート順に参照します。
サーバーは、クライアントホスト名およびユーザー名が一致した最初の行を使用します。
サーバーは、具体性がもっとも高い Host
値が先になるように行を並べるソートルールを使用します。リテラルのホスト名および IP アドレスは具体性がもっとも高くなります。(リテラルの IP アドレスの具体性は IP アドレスがネットマスクを持つかどうかによって影響されないため、192.168.1.13
と 192.168.1.0/255.255.255.0
の具体性は同等とみなされます。)パターン '%'
は「任意のホスト」を意味するため、具体性はもっとも低くなります。空の文字列 ''
も「任意のホスト」を意味しますが、'%'
のあとにソートされます。同じ Host
値を持つ行は、もっとも具体的な User
値が最初になるよう並べられます (ブランクの User
値は 「任意のユーザー」を意味し、具体性がもっとも低くなります)。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 | ...
| thomas.loc.gov | | ...
+----------------+----------+-
ソート済みテーブルは次のようになります。
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| thomas.loc.gov | | ...
| % | jeffrey | ...
+----------------+----------+-
jeffrey
による thomas.loc.gov
からの接続は最初の行に一致しますが、jeffrey
による任意のホストからの接続は 2 番目の行に一致します。
よくある誤解として、ある特定のユーザー名についてサーバーが接続に対する一致を検出しようとしたとき、そのユーザーの名前を明示的に指定するすべての行が最初に使用されるという認識があります。これは正しくありません。このことは前述の例によって説明され、jeffrey
による thomas.loc.gov
からの接続は、User
カラム値として 'jeffrey'
を格納している行ではなく、ユーザー名のない行が最初に一致します。その結果、jeffrey
は接続するときにユーザー名を指定したにもかかわらず、匿名ユーザーとして認証されます。
サーバーに接続できても権限が期待したものとは異なる場合、おそらくほかのアカウントとして認証されています。サーバーがユーザーの認識に使用したアカウントを見つけるには、CURRENT_USER()
関数を使用します。(セクション12.14「情報関数」を参照してください。)これは、一致する user
テーブル行の User
および Host
値を示す、
形式の値を返します。たとえば、user_name
@host_name
jeffrey
が接続して、次のクエリーを発行したとします。
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
ここで表示された結果は、一致した user
テーブル行の User
カラム値がブランクであることを示しています。つまり、サーバーは jeffrey
を匿名ユーザーとして扱っています。
認証の問題を診断するための別の方法は、user
テーブルを出力し、テーブルを手作業でソートして、最初の一致が行われた行を確認する方法です。