データベースを保護するトップ7のMySQLセキュリティベストプラクティス

アクセス制御、ネットワーク公開、TLS、パッチ適用、ログ記録、暗号化に関する7つの実用的なMySQLセキュリティチェック。

MySQLデータベースを保護するためのセキュリティベストプラクティス トップ7

MySQLのセキュリティは、誰が接続できるか、何ができるか、そしてホストが侵害された場合に何が露出するかを減らすことから始まります。以下の7つのチェックは、単一の設定でMySQLを「安全」にできると偽ることなく、本番データベースの実用的なベースラインを提供します。

1. ユーザーアクセス管理の強化

誰がデータベースにアクセスでき、何ができるかを制御することは、防御の第一線です。これには、最小権限の原則に従って特定のユーザーアカウントを作成することが含まれます。つまり、ユーザーはタスクを実行するために必要な権限のみを持つべきです。

強力なアカウントを作成する

共有アプリケーションユーザーや弱いパスワードを避けてください。セルフマネージドサーバーでは mysql_secure_installation を使用して、匿名ユーザーを削除し、該当する場合はテストデータベースを削除し、初期のrootアカウント設定を強化します。

最小限の権限を付与する

アプリケーションが必要とする特定のデータベース、テーブル、アクションに対して GRANT ステートメントを使用します。アプリケーションアカウントには ALL PRIVILEGES を避けてください。

例:

CREATE USER 'webapp_user'@'10.0.10.%' IDENTIFIED BY '実際の秘密を使用してください';

GRANT SELECT, INSERT, UPDATE ON mydatabase.* TO 'webapp_user'@'10.0.10.%';

通常の CREATE USER または GRANT ステートメントの後に FLUSH PRIVILEGES は必要ありません。MySQLはこれらのステートメントに対して自動的に権限テーブルを更新します。

定期的にアカウントを監査します:

SELECT user, host, account_locked FROM mysql.user ORDER BY user, host;
SHOW GRANTS FOR 'webapp_user'@'10.0.10.%';

2. ネットワークアクセスを制限する

MySQLへのネットワークパスを制限します。有効なデフォルトはMySQLのバージョンとパッケージに依存するため、ローカルでのみリッスンしていると仮定せずに、実行中のサーバーを確認してください。

リスナーを確認:

ss -ltnp | grep 3306

ローカルクライアントのみがアクセスする必要がある場合は、MySQLをlocalhostにバインドします:

[mysqld]
bind-address = 127.0.0.1

アプリケーションサーバーがリモートで接続する場合は、プライベートインターフェースにバインドし、セキュリティグループ、ファイアウォール、またはネットワークACLを使用して、それらのソースのみがポート 3306 にアクセスできるようにします。

3. 接続にTLSを使用する

転送中のデータを暗号化することで、盗聴や中間者攻撃を防ぎます。MySQLはクライアント-サーバー接続のためのSSL/TLS暗号化をサポートしています。

サーバー設定は通常次のようになります:

[mysqld]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/server-cert.pem
ssl-key=/path/to/server-key.pem

クライアントの例:

mysql -h your_host -u your_user -p --ssl-mode=REQUIRED

より厳格な検証には、証明書と一致するホスト名で --ssl-mode=VERIFY_IDENTITY を使用します。REQUIRED は接続を暗号化しますが、サーバーIDを強く検証しません。

4. MySQLを最新に保つ

ソフトウェアの脆弱性は頻繁に発見され、パッチが適用されます。古いバージョンのMySQLを実行すると、既知のエクスプロイトにデータベースがさらされる可能性があります。

実行しているリリースストリームを追跡し、セキュリティアップデートを適用し、本番環境に適用する前にステージング環境でアップグレードをテストします。マネージドデータベースサービスを使用する場合は、プロバイダーのメンテナンスポリシーを確認し、チームが実際に監視するメンテナンスウィンドウを設定します。

5. MySQLサーバー設定を強化する

ネットワークバインディング以外にも、セキュリティを強化できる設定オプションがいくつかあります。

アプリケーションが LOAD DATA LOCAL INFILE を必要としない限り、local_infile を無効にします:

[mysqld]
local_infile = 0

設定ファイル、TLSキー、バックアップ認証情報は、適切なシステムユーザーのみが読み取れるようにします。また、インストールされているプラグインを確認し、使用しないものは削除します。

6. ログの監査と監視

ログ記録は、不審なアクティビティを検出し、セキュリティインシデント後のフォレンジック分析に不可欠です。

MySQL Enterpriseには監査ログプラグインが含まれています。コミュニティデプロイメントでは、環境に応じて、オペレーティングシステムログ、エラーログ、プロキシログ、クラウドデータベース監査機能、またはサードパーティの監査プラグインがよく使用されます。

少なくとも以下を監視します:

  • 失敗したログインと認証エラー。
  • 新しいユーザー、変更された権限、特権ステートメント。
  • 予期しないホストからの接続。
  • バックアップジョブの失敗とリストアテストの失敗。

特定の短期的なトラブルシューティングの必要性がない限り、ビジーな本番サーバーで一般クエリログを有効にしたままにしないでください。大量のI/Oを生成し、機密性の高いクエリ値をキャプチャする可能性があります。

7. 保存データの保護

SSL/TLSは転送中のデータを保護しますが、保存データの暗号化は、基盤となるストレージが侵害された場合にデータを保護します。

広範なベースラインとして、ストレージまたはボリューム暗号化を使用します。機密フィールドについては、データベースがデータを復号化するために必要なすべてを保持しないように、アプリケーションレベルの暗号化を検討します。

MySQLには AES_ENCRYPT()AES_DECRYPT() などの暗号化関数もありますが、キーをSQLにハードコードしたり、データの隣に保存したりしないでください。

簡略化された例:

UPDATE users
SET sensitive_data = AES_ENCRYPT('user_private_info', @encryption_key)
WHERE user_id = 1;

SELECT AES_DECRYPT(sensitive_data, @encryption_key)
FROM users
WHERE user_id = 1;

実際のシステムでは、適切なキー管理プロセスを使用してください。キーのローテーション、アクセス制御、キーマテリアルのバックアップがない暗号化は、回復可能なインシデントを永久的なデータ損失に変える可能性があります。

まとめ

最もリスクを取り除くコントロールから始めましょう:最小権限ユーザー、プライベートネットワークアクセス、TLS、パッチ適用、テスト済みバックアップ。次に、コンプライアンスと脅威モデルに一致する監査ログと暗号化コントロールを追加します。主要なスキーマ、インフラストラクチャ、またはアクセスの変更のたびに設定を見直してください。