シェア

はじめに

認証と認可は、MySQLサーバーを管理および保護するために不可欠な考慮事項です。認証(「authn」と略されることもあります)は、クライアントが特定のユーザーとして接続することを許可されていることを検証するポリシーとメカニズムのクラスを指します。認可(「authz」と略されることもあります)は、認証後に発生し、アカウントに許可されているアクションを決定するプロセスです。

このガイドでは、MySQLがこのアクセス制御システムを管理するために提供する概念とコンポーネントを見ていきます。ユーザー、ロール、認証方法、および権限間の相互作用について説明します。これらは一体となって、MySQLデータベースサーバーで誰が何をできるかを制御する方法という問題を解決します。

MySQLは認証と認可をどのように設定しますか?

MySQLは、認証と認可の要件を、いくつかの異なる関連システムを通じて管理します。大まかに言えば、その構成要素は次のとおりです。

  • ユーザー:ユーザーは、MySQLサーバー上で構成された個々のアカウントであり、IDとして機能します。これらのIDは、認証方法と組み合わせて、クライアントがユーザーで接続できるようにすることができ、さまざまなレベルの粒度でさまざまなデータベースオブジェクトにアクセスして制御できるように権限を付与できます。MySQLのユーザーは、User名と、ユーザーが接続しているHostで構成されています。異なるHostから接続する同じUser名は、異なるユーザーと見なされます。
  • 認証方法:認証方法とは、接続しているクライアントが特定のユーザーアカウントを使用することを許可されるべきかどうかを判断する方法です。この方法には、クライアントからパスワードを受け入れて検証することが含まれることが多いですが、他の認証方法も利用できます。
  • 権限:ユーザーの機能とアクセスレベルは、ユーザーに直接、ロールメンバーシップを通じて、またはオブジェクトの所有権を通じて付与された権限によって定義されます。これらはさまざまなスコープで定義され、ユーザーが試みる各アクションに対してチェックされます。
  • ロール:実際的な意味で、ロールはユーザーに適用できる権限のセットです。関連する権限のグループをロールに追加し、ロールメンバーシップを介してそれらの権限を割り当てることで、権限管理を簡素化できます。

実際のアクセス制御プロセスは、2つの明確な部分に分かれています。まず、クライアントは特定のユーザーとしてサーバーに対して認証を行います。その後、すべてのアクションは、ユーザーの承認された権限に対してチェックされ、各リクエストを許可または拒否するかどうかを決定します。

パート1:認証

MySQLのアクセス制御システムの最初の段階は、接続を認証することです。MySQLは、次の要因に基づいて接続リクエストを受け入れるかどうかを決定します。

  • リクエストしているユーザーアカウントとして正しく認証できるかどうか
  • そのユーザーアカウントがシステム内でロックされているかどうか

接続しようとしているユーザーがロック解除されており、正しく認証できる場合、MySQLは接続を受け入れ、アクセス制御システムのパート2に進むことができます。ユーザーがロックされているとマークされている場合、認証試行が失敗した場合、または指定したユーザーが無効な場合、MySQLは接続リクエストを拒否します。

これらの機能を実行するために、MySQLは内部mysqlデータベース内のuserテーブル内の次の列を参照します。

User

クライアントが接続しているユーザー名は、MySQLがユーザーを認証する方法を決定するのに役立ちます。以下のHostフィールドと組み合わせることで、MySQL内で完全で一意のIDを形成します。

mysql.userテーブルでは、空白のUser値は、クライアントによって提供された任意のユーザーに一致します。ただし、これが起こると、クライアントはセッションの間、匿名ユーザーと見なされます。これは、アクセス制御の第2段階に影響を与えます。ここでは、サーバーは、クライアントが提供したユーザーではなく、匿名ユーザーに対してアクションをチェックします。

Host

クライアントが接続しているホストは、ユーザーのIDの重要な部分と見なされます。MySQLでは、一意のIDは、ユーザー名と接続元のホストの組み合わせから形成されます。

したがって、example.comからのuser1は、test.orgからのuser1とは異なるものと見なされます。UserフィールドとHostフィールドは、MySQLに認証を試みるアカウントを指示するために連携します。

plugin

MySQLがUserHostを使用して接続リクエストの正しいレコードを特定すると、pluginフィールドを使用して、クライアントをどのように認証するかを決定します。

ユーザーのpluginフィールドは、ユーザーの資格情報を検証するために使用する必要がある認証方法を定義します。デフォルトのプラグインであるcaching_sha2_passwordは、テーブル内に保存されているパスワードのハッシュバージョンに対してユーザーのパスワードをチェックします。

authentication_string

「ネイティブ」認証プラグイン(mysql.userテーブル内の情報のみを使用してユーザーを認証するもの)の場合、authentication_string列には、ユーザーのパスワードを照合する文字列が含まれています。ほとんどの場合、これはパスワードのハッシュバージョンです。ネイティブプラグインのauthentication_stringmysql.userテーブルで空白の場合、クライアントは正常に認証するためにパスワードを指定しないでください

認証に外部システムを使用するプラグインの場合、authentication_stringは、外部システムがユーザーを正しく認証するために必要な追加情報(サービス名、追加の識別情報など)を指定するためによく使用されます。

account_locked

この列は、この特定のユーザーアカウントがシステム内でロックされているかどうかを決定します。アカウントは、データベース管理者によって手動でロックできます。続行するには、アカウントのロックを解除する必要があります。

mysql.userテーブル内の行の優先順位の決定

MySQLは、上記の5つのフィールドを使用して、接続を受け入れるかどうかを決定します。ただし、複数のエントリがクライアントの接続に一致する場合があります。たとえば、クライアントがホストを提供しない場合や、mysql.userテーブルにユーザーなしの行が含まれている可能性があります。MySQLは、クライアントを認証する方法を決定するために、これらの行の優先順位を確立する方法が必要です。

これを行うために、MySQLは、サーバーが起動したとき、またはディスクから情報をリロードするように信号が送信されたときに、mysql.userテーブルからメモリに行を読み取ります。行を読み取るときに、MySQLは具体性によって行をソートし、テーブル内の行が最も具体的から最も具体的でない順に並べられるようにします。

まず、MySQLはHost列の具体性に基づいて行をソートします。完全なドメイン名またはIPアドレスで構成されるHostを持つ行は、パイルの先頭にソートされ、次にHostフィールドでワイルドカードを使用する行(のみ%、すべて一致するワイルドカードを含む行を、最も具体的でないエントリとして最後に配置)、最後に空白のHostを持つ行が続きます。

MySQLは、User列を2番目のソートフィールドとして使用します。これは、2つの行が同じHostの具体性を持っている場合、より具体的なUserエントリを持つ行が優先されることを意味します。ワイルドカードはUserフィールドでは許可されていません。

Userフィールドは、次のいずれかで構成されます。

  • 提供されたユーザー名と完全に一致する必要がある文字列、または
  • クライアントによって提供された任意のユーザー名に一致するが、匿名ユーザーとしてセッションを続行する空白のフィールド

MySQLは、mysql.userテーブルから最大1行を使用してクライアント接続を認証します。これは、認証が失敗した場合、または間違った行が一致した場合、正しく認証される可能性のある代替案をチェックしないことを意味します。クライアント接続リクエストを認証するために使用する行を決定するために、MySQLはソートされたリストの先頭から開始します。各行を順番にチェックし、クライアント接続に一致する最初に見つかった行を使用します。

上記のソート順序に注意しないと、これは驚くべき影響を与える可能性があります。たとえば、Host値を含むが行を含まないUser行は、User値を含みHostを含まない行よりも常に優先して選択されます。このソートシステムを理解することは、認証の問題のクラス全体を回避するのに役立ちます。

特定のユーザーで認証に問題がある場合は、一致するより具体的なエントリがないか確認してください。接続できるが、できるはずだと思うアクションを実行できない場合は、MySQLが要求されたユーザー名としてアクセスを許可しているか、上記のように発生する可能性のある匿名ユーザーとしてアクセスを許可しているかを確認してください。

このコマンドは、現在認証されているユーザーを出力します。

SELECT CURRENT_USER()

パート2:認可

クライアントの資格情報が認証されると、MySQLは接続を確立し、アクセス制御システムの2番目のパートに入り、認可を決定します。MySQLの認可は、ユーザーアカウントの特定の権限に対して各コマンドをチェックする継続的なプロセスです。コマンドがユーザーの権限の範囲内にある場合、アクションは許可されます。そうでない場合、サーバーはリクエストを拒否します。

さまざまな種類の権限

特定の権限がどこに保存されているかを説明するために、MySQL内のさまざまな種類の権限について説明する必要があります。

権限スコープ

権限は異なるスコープで割り当てることができ、付与された権限の効果範囲を決定します。一部の権限は特定のスコープでのみ有効ですが、有効にする粒度に応じて、他の権限は異なるスコープで割り当てることができます。

グローバル権限は、特定のデータベースに関連付けられていない権限です。これらは、MySQLサーバー全体で有効です。多くのグローバル権限はシステム管理に関連しており、データ管理に直接関連するのではなく、システム管理責任に関連付けられています。

データベース権限は、MySQLサーバー内の特定のデータベースに関連付けられています。データベーススコープで付与された権限は、ユーザーがデータベースに対して実行できること、および内部に含まれるデータベースオブジェクト(テーブルなど)に影響を与えます。データベース権限は、特定のデータベースに付与することも、データベース全般に付与することもできます。

オブジェクト権限を使用すると、データベース内のテーブル、インデックスなどを制御できます。これらの権限は、特定のオブジェクト、特定のデータベース内の特定のタイプのすべてのオブジェクト、またはサーバー全体の特定のタイプのすべてのオブジェクトに付与できます。

静的権限と動的権限

内部的には、権限は静的または動的のいずれかに分類できます。

静的権限はサーバーに組み込まれており、登録解除(無効化)することはできません。これらの権限は、サーバーでどのコンポーネントが有効になっているかに関係なく、常に利用可能です。一般に、静的権限は通常、すべてのシステムまたはほとんどのシステムに適用可能な基本的な権限(たとえば、データを読み書きする機能など)です。

動的権限は、一方、それらを定義するプラグインまたはコンポーネントの可用性に依存します。これらの権限は、実行時に登録または登録解除して、可用性に影響を与えることができます。登録解除された権限は付与できませんが、すでに付与されている権限は起動時に自動的に登録されます。動的権限は常にグローバルスコープ(MySQLサーバー全体に適用)です。

権限が定義されている場所

MySQLの権限は、内部mysqlシステムデータベースの多くの異なるテーブルで定義されています。内部で定義された権限の組み合わせにより、アクションまたはデータベースオブジェクトに対するユーザーの特定の権限が決定されます。mysqlデータベースの次のテーブルは、権限の定義に関与しています。

  • user:認証用のユーザーアカウントの定義に加えて、userテーブルは、各ユーザーの静的グローバル権限も定義します。これらの権限は、MySQLサーバー全体に適用され、プラグインまたはコンポーネントの可用性の影響を受けません。
  • global_grantsglobal_grantsテーブルは、各ユーザーの動的グローバル権限を定義します。プラグインまたはコンポーネントによって定義された権限は、このテーブルに登録されます。
  • dbdbテーブルは、データベースレベルの権限を定義します。dbテーブルは、userテーブルと同様に、ユーザーのUser値とHost値を照合しますが、行のデータベーススコープを定義するDbという列も持っています。
  • tables_privtables_privテーブルは、dbテーブルがデータベースに対して行うのと同様の方法で、テーブルレベルの権限を定義します。テーブルレベルのスコープを有効にするために、UserHost、およびDbに加えて、Table_nameという列を使用できます。
  • columns_privtables_privテーブルよりもさらに一歩進んだcolumns_privテーブルは、列レベルでのアクセスを決定します。この追加の粒度を追加するために、tables_privテーブル内で使用可能な列に加えて、Column_nameという列が含まれています。
  • procs_privprocs_privテーブルは、プロシージャと関数を実行するための権限を定義します。これは、UserHostDbRoutine_name、およびRoutine_type列を使用して、さまざまな種類のプロセスに対するユーザーの権限をスコープします。
  • proxies_privproxies_privテーブルは、ユーザーのプロキシ権限を定義します。プロキシを使用すると、あるユーザーが別のユーザーとして機能し、その権限を継承できます。proxies_privテーブルは、User列とHost列を使用してユーザーを一致させ、次に、一致したユーザーが誰として機能できるかを定義するために、Proxied_host列とProxied_user列を個別に使用します。

これらのテーブルのユーザーアカウントのマッチングは、以前にmysql.userテーブルがメモリに読み込まれてソートされる方法について説明した方法と同様に機能します。

ユーザーに現在関連付けられている権限を表示するには、次のように入力します。

SHOW GRANTS FOR '<user>'@'<host>';

権限のないアカウントプロパティも、次のようにして確認できます。

SHOW CREATE USER '<user>'@'<host>';

ロール

ロールは、認可プロセスにも適合する関連コンポーネントです。ロールとは、管理者が特権の管理を容易にするために作成できる、名前付きの特権のまとまりのことです。特権のグループがロールに付与されると、ユーザーをロールのメンバーとして追加することで、それらの特権をユーザーに付与できます。

したがって、複数のユーザーに特定のテーブル内で値を挿入および更新する機能を提供したい場合は、それらの特権を持つロールを作成できます。次に、そのロールにユーザーを追加または削除することで、そのテーブルに対する挿入および更新を許可するユーザーを制御できます。これにより、さまざまなタイプのユーザーに対して特定の定義されたアクセスレベルが作成され、アクセスレベルがアカウント全体で一貫して適用されるようになります。

ロールが関与する認証プロセスの複雑さへの影響は最小限です。ただし、ここでは特権を管理する方法としての有用性について言及します。

結論

認証と認可は、MySQLのセキュリティアプローチの重要な要件です。これらは連携して、サーバーに接続できるユーザー、表示および操作できる構造、およびアクセスできるデータを規制することにより、システムのアクセス制御コントローラーとして機能します。これらのシステムがどのように相互作用するかを理解することで、すべての正当なアクションを妨げることなくデータを保護する安全なポリシーを構成できます。

著者について
Justin Ellingwood

ジャスティン・エリングウッド

ジャスティンは、2013年からデータベース、Linux、インフラストラクチャ、および開発者ツールについて執筆しています。彼は現在、妻と2羽のウサギと共にベルリンに住んでいます。彼は通常、三人称で書く必要はありません。これは関係者全員にとって安心です。