MySQLユーザー権限の付与と取り消しのベストプラクティス

MySQLのGRANT、REVOKE、SHOW GRANTS、DROP USERを安全に使用し、アプリケーションアカウントと管理者アカウントに対する最小権限の例を紹介します。

MySQLユーザー権限の付与と取り消しのベストプラクティス

MySQLの権限は、アプリケーション、ツール、管理者が接続後に何を実行できるかを決定します。広範なアクセス権を持つ単一のアカウントは、小さなバグやパスワード漏洩をデータベース全体の露出に変える可能性があります。

GRANTREVOKESHOW GRANTSを最小権限の原則に従って使用します。各アカウントは、使用するホストからのみ、必要な権限のみを持つべきです。

MySQL権限の理解

GRANTREVOKEに取り組む前に、MySQLで利用可能な権限のさまざまなスコープと種類を理解することが重要です。権限は、ユーザーが実行できるアクションと、どのデータベースオブジェクトに対してかを定義します。

MySQLの権限は、そのスコープによって分類できます。

  • グローバル権限(*.*: MySQLサーバー上のすべてのデータベースとテーブルに適用されます。例としては、SUPERPROCESSRELOADCREATE USERなどがあります。
  • データベース権限(database_name.*: 特定のデータベース内のすべてのテーブルとオブジェクトに適用されます。例としては、SELECTINSERTUPDATEDELETECREATEDROPなどがあります。
  • テーブル権限(database_name.table_name: 特定のテーブル内のすべてのカラムに適用されます。例としては、SELECTINSERTUPDATEDELETEALTERなどがあります。
  • カラム権限(database_name.table_name.column_name: テーブル内の特定のカラムに適用されます。これはあまり一般的ではありませんが、高度に細かい制御に役立ちます。
  • ルーチン権限(database_name.routine_name: ストアドプロシージャと関数に適用され、EXECUTEALTER ROUTINEを制御します。
  • プロキシ権限: あるユーザーが別のユーザーとして動作することを許可します。これは、ユーザーIDを管理するアプリケーションに役立ちます。

一般的な特定の権限には次のものがあります。

  • SELECT: テーブルからデータを読み取ります。
  • INSERT: テーブルに新しい行を追加します。
  • UPDATE: テーブルの既存の行を変更します。
  • DELETE: テーブルから行を削除します。
  • CREATE: データベース、テーブル、またはインデックスを作成します。
  • DROP: データベース、テーブル、またはインデックスを削除します。
  • ALTER: テーブル構造を変更します。
  • INDEX: インデックスを作成または削除します。
  • REFERENCES: 外部キー制約を確立します。
  • CREATE VIEWSHOW VIEW: ビューを管理します。
  • CREATE ROUTINEALTER ROUTINEEXECUTE: ストアドプロシージャと関数を管理および実行します。
  • FILE: サーバーホスト上のファイルを読み書きします(非常に強力で、細心の注意を払って使用してください)。
  • GRANT OPTION: ユーザーが自分の権限を他のユーザーに付与できるようにします。これは非常に強力な権限であり、控えめに付与する必要があります。

GRANTコマンド: 権限を安全に付与する

GRANTコマンドは、MySQLユーザーに権限を割り当てるために使用されます。権限を付与するときは、最小権限の原則(絶対に必要なものだけを付与する)を考慮することが重要です。

基本構文

GRANTコマンドの一般的な構文は次のとおりです。

GRANT privileges ON object TO 'user'@'host' [WITH GRANT OPTION];
  • privileges: 権限のカンマ区切りリスト(例:SELECT, INSERT)。
  • object: スコープを指定します(例:グローバルは*.*database_name.*database_name.table_name)。
  • 'user'@'host': ユーザーアカウント。ユーザー名と接続元のホストを含みます。hostは、IPアドレス、ホスト名、またはワイルドカード(任意のホストは%、ローカル接続はlocalhost)です。
  • WITH GRANT OPTION:(オプション)ユーザーが指定された権限を他のユーザーに付与できるようにします。

パスワードはCREATE USERALTER USERで作成または変更します。古いMySQLリリースではGRANT ... IDENTIFIED BYが許可されていましたが、最新のMySQL構文ではアカウント作成を分離しています。

実用的な例

いくつかの一般的なシナリオを見てみましょう。

  1. 新しいユーザーを作成し、グローバル読み取り専用アクセスを付与する(推奨されません)

    CREATE USER 'global_reader'@'localhost' IDENTIFIED BY 'StrongPass123!';
    GRANT SELECT ON *.* TO 'global_reader'@'localhost';
    

    警告: *.*SELECTを付与すると、すべてのデータベースとテーブルへのアクセスが許可されます。これは通常、アプリケーションユーザーには広すぎるため、特定の管理タスクに絶対に必要な場合を除き、避けるべきです。

  2. アプリケーションユーザーに特定のデータベースへのフルアクセスを付与する

    アプリケーションユーザーが自身のデータベース内でデータを管理する必要がある一般的なシナリオ。

    CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'AppPassSecure!';
    GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp_db`.* TO 'app_user'@'localhost';
    

    ここで、app_usermyapp_dbデータベース内でのみ基本的なCRUD操作を実行できますが、新しいテーブルを作成したりスキーマを変更したりすることはできません。

  3. 特定のテーブルへの読み取り専用アクセスを付与する

    特定のテーブルからのみ読み取る必要があるレポートツールの場合。

    CREATE USER 'report_tool'@'%' IDENTIFIED BY 'ReportSecret!';
    GRANT SELECT ON `sales_db`.`orders` TO 'report_tool'@'%';
    

    '%'ホストにより、report_toolは任意のホストから接続できますが、sales_dbordersテーブルに対するSELECTアクセスのみです。

  4. GRANT OPTIONを付与する(細心の注意を払って使用)

    管理者が特定のデータベースの権限管理を委任する必要がある場合。

    CREATE USER 'db_admin'@'localhost' IDENTIFIED BY 'AdminPass#456';
    GRANT ALL PRIVILEGES ON `inventory_db`.* TO 'db_admin'@'localhost' WITH GRANT OPTION;
    

    db_adminは、inventory_dbに対する任意の権限を他のユーザーに付与できるようになりました。これは中央管理をバイパスする強力な権限であり、やむを得ない場合にのみ使用する必要があります。

権限付与のヒント

  • 最小権限の原則: ユーザーまたはアプリケーションが機能するために必要な最小限の権限セットを常に付与します。専用のデータベース管理者アカウントでない限り、ALL PRIVILEGESは避けてください。
  • 特定のホスト: 可能な場合は、'%'の代わりに、ユーザー接続を特定のIPアドレスまたはホスト名('user'@'192.168.1.10'または'user'@'appserver.example.com')に制限します。
  • ユーザーを分離する: 同じデータベースにアクセスする場合でも、異なるアプリケーションやサービスごとに個別のユーザーアカウントを作成します。これにより、潜在的なセキュリティ侵害を分離できます。
  • アプリケーションにrootを使用しない: アプリケーションにrootユーザーアカウントを決して使用しないでください。専用の最小権限ユーザーを作成します。

REVOKEコマンド: 権限を効果的に取り消す

REVOKEコマンドは、MySQLユーザーから権限を削除するために使用されます。これは、ロールが変更されたりアプリケーションが廃止されたりした場合に、安全なデータベース環境を維持するためにGRANTと同じくらい重要です。

基本構文

REVOKEコマンドの一般的な構文は次のとおりです。

REVOKE privileges ON object FROM 'user'@'host';
  • privileges: 取り消す権限のカンマ区切りリスト。
  • object: 取り消し元のスコープ(権限が付与されたスコープと一致する必要があります)。
  • 'user'@'host': 権限を取り消すユーザーアカウント。

実用的な例

  1. アプリケーションユーザーからDELETE権限を取り消す

    アプリケーションがデータを削除する必要がなくなった場合、または権限をダウングレードしたい場合。

    REVOKE DELETE ON `myapp_db`.* FROM 'app_user'@'localhost';
    

    これで、app_usermyapp_db内でSELECTINSERTUPDATEは引き続き実行できますが、DELETEは実行できなくなります。

  2. 委任された管理者からGRANT OPTIONを取り消す

    db_admininventory_dbに対する他のユーザーの権限を管理する必要がなくなった場合。

    REVOKE GRANT OPTION ON `inventory_db`.* FROM 'db_admin'@'localhost';
    

    : GRANT OPTIONを取り消すには、REVOKE文でGRANT OPTIONを明示的に指定する必要があります。

  3. 特定のデータベースに対するすべての権限を取り消す

    ユーザーが特定のデータベースに対して持っているすべての権限を削除します。

    REVOKE ALL PRIVILEGES ON `old_db`.* FROM 'old_app'@'%';
    

    警告: *.*に対するREVOKE ALL PRIVILEGESは、すべてのグローバル権限を取り消します。これにはSUPERCREATE USERなどが含まれる可能性があります。このスコープをグローバルに使用する場合は注意してください。

  4. ユーザーアカウントを削除する

    ユーザーまたはアプリケーションが不要になった場合は、ユーザーを完全に削除するのが最善です。

    DROP USER 'report_tool'@'%';
    

    このコマンドは、ユーザーとそれに関連するすべての権限を削除します。

権限取り消しのヒント

  • スコープを一致させる: 取り消し時には、オブジェクトスコープ(*.*database_name.*など)が権限が元々付与された方法と正確に一致することを確認してください。database_name.*に対してSELECTを付与した場合は、database_name.*から取り消す必要があり、database_name.table_nameからではありません。
  • 確認する: 権限の付与または取り消し後は、常にSHOW GRANTS FOR 'user'@'host';を使用して変更を確認します。
  • 不要なフラッシュを避ける: GRANTREVOKECREATE USERDROP USERの後にFLUSH PRIVILEGESは必要ありません。MySQLはこれらのステートメントを即座に適用します。
  • 連鎖的な影響を考慮する: GRANT OPTIONを持つユーザーが他のユーザーに権限を付与した場合、そのユーザーのGRANT OPTIONを取り消しても、付与された権限は自動的には取り消されません。これらは個別に取り消す必要があります。

MySQLユーザー権限管理のベストプラクティス

堅牢な権限管理戦略を実装することは、データベースのセキュリティにとって重要です。

1. 最小権限の原則(PoLP)

これは黄金律です。ユーザーまたはアプリケーションが意図された機能を実行するために必要な最小限の権限のみを付与します。例:

  • レポートツールにはSELECTが必要です。
  • ウェブアプリケーションには通常、SELECTINSERTUPDATEDELETEが必要です。
  • ETLプロセスには、INSERTUPDATEDELETECREATE TABLEDROP TABLEが必要な場合があります(ただし、特定のステージングスキーマに限ります)。

2. 専用のユーザーアカウント

  • 共有アカウントを避ける: 各アプリケーション、サービス、管理ユーザーは、独自のMySQLユーザーアカウントを持つ必要があります。これにより、監査とアクティビティの追跡が容易になります。
  • アプリケーションにrootを使用しない: アプリケーションがrootユーザーとして接続するように構成しないでください。rootユーザーは無制限のアクセス権を持ち、人間の管理者による重要な管理タスクにのみ使用する必要があります。

3. 強力なパスワードとパスワードローテーション

  • すべてのMySQLユーザーアカウントに強力で一意のパスワードを適用します。可能であれば、MySQLのパスワード検証プラグインを利用します。
  • 特に特権の高いアカウントについては、定期的なパスワードローテーションポリシーを実装します。

4. ホスト制限

  • 可能な場合は、ユーザー接続を特定のIPアドレスまたはホスト名に制限します。'%'localhost、アプリケーションサーバーのIP、またはネットワークサブネット('user'@'192.168.1.%')に置き換えます。これにより、未知の場所からの不正なアクセス試行を防ぎます。

5. 定期的な監査とレビュー

  • すべてのユーザーアカウントとそれに関連する権限を定期的にレビューします。廃止されたアカウントや不要な権限を削除します。
  • SHOW GRANTS FOR 'user'@'host';を使用して権限を検査します。
  • 大規模な環境を監査するための自動化ツールを検討します。

6. 権限を文書化する

  • データベースユーザー、そのロール、および各ユーザーに付与された権限の明確なドキュメントを維持します。これにより、一貫性を維持し、セキュリティ監査を容易にします。

7. 開発、ステージング、本番環境を分離する

  • 開発環境やステージング環境で本番環境の認証情報を決して使用しないでください。各環境には、独自の異なるユーザーと権限のセットが必要です。

8. 絶対に必要な場合を除き、GRANT OPTIONを避ける

  • WITH GRANT OPTIONを付与すると、権限管理がそのユーザーに委任され、中央のセキュリティポリシーをバイパスする可能性があります。これは、非常に信頼できる管理ユーザーのみに、可能な限り制限されたスコープで予約してください。

現在の権限の表示

ユーザーに割り当てられた権限を確認するには、SHOW GRANTSコマンドを使用します。

SHOW GRANTS FOR 'username'@'host';

例:

SHOW GRANTS FOR 'app_user'@'localhost';

出力は次のようになります。

+-------------------------------------------------------------+
| Grants for app_user@localhost                               |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'app_user'@'localhost'                |
| GRANT SELECT, INSERT, UPDATE ON `myapp_db`.* TO 'app_user'@'localhost' |
+-------------------------------------------------------------+

GRANT USAGE ON *.*行は、ユーザーにグローバル権限がなく、接続する機能のみがあることを示しています。

まとめ

MySQLの権限管理は、狭く、レビュー可能に保ちます。専用のアカウントを作成し、ホストを制限し、最小の有用なスコープで必要なアクションのみを付与し、すべての変更をSHOW GRANTSで確認します。アプリや担当者がアクセスを必要としなくなった場合は、古い資格情報を残すのではなく、権限を取り消すかアカウントを削除します。