共有

はじめに

認証と認可は、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テーブルの行をメモリに読み込みます。行を読み込む際に、それらを特異度(specificity)でソートし、テーブル内の行が最も特異なものから最も特異でないものへと順序付けられるようにします。

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

MySQLはUser列を二次的なソートフィールドとして使用します。これは、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サーバー内の特定のデータベースに紐付けられています。データベーススコープで付与された権限は、ユーザーがそのデータベースに対して実行できること、およびその中に含まれる任意のデータベースオブジェクト(テーブルなど)に対して実行できることに影響を与えます。データベース権限は、特定のデータベースに付与することも、一般的にデータベースに対して付与することもできます。

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

静的権限 vs 動的権限

内部的には、権限は静的または動的に分類できます。

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

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

権限の定義場所

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

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

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

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

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

また、権限以外のユーザープロパティも表示できます。

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

ロール

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

したがって、特定のテーブル内で値を挿入および更新する能力を複数のユーザーに与えたい場合、それらの権限を持つロールを作成できます。次に、そのロールにユーザーを追加または削除することで、そのテーブルで誰が挿入および更新できるかを制御できます。これにより、異なる種類のユーザーに対して特定の定義されたアクセスレベルが作成され、アクセスレベルがアカウント全体で一貫して適用されることを保証するのに役立ちます。

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

まとめ

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

著者について
Justin Ellingwood

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

ジャスティンは2013年からデータベース、Linux、インフラストラクチャ、開発者ツールについて執筆しています。現在はベルリンで妻と2匹のウサギと暮らしています。通常、三人称で書く必要がないため、関係者全員にとって安心です。
© . All rights reserved.