はじめに
この実験では、MySQL データベースのセキュリティを強化する方法を学びます。rootユーザーのパスワード設定、最小権限の原則に基づいた専用ユーザーの作成、ユーザー権限の管理、匿名アカウントの削除といった、不可欠なセキュリティベストプラクティスを網羅します。この実験を終える頃には、一般的な脆弱性から MySQL サーバーを保護する方法について、より深く理解できるようになるでしょう。
この実験では、MySQL データベースのセキュリティを強化する方法を学びます。rootユーザーのパスワード設定、最小権限の原則に基づいた専用ユーザーの作成、ユーザー権限の管理、匿名アカウントの削除といった、不可欠なセキュリティベストプラクティスを網羅します。この実験を終える頃には、一般的な脆弱性から MySQL サーバーを保護する方法について、より深く理解できるようになるでしょう。
デフォルトの MySQL インストールでは、多くの場合、ローカルマシンからの接続時にrootユーザーがパスワードなしで接続できます。MySQL を保護するための最初のステップは、rootアカウントに強力なパスワードを設定することです。
まず、デスクトップからターミナルを開きます。
rootユーザーとして MySQL サーバーに接続します。この実験環境では、sudoを使用してパスワードなしで接続できます。
sudo mysql -u root
接続すると、MySQL プロンプト(mysql>)が表示されます。
次に、rootユーザーのパスワードを設定します。ALTER USERステートメントは、ユーザーアカウントを変更するために使用されます。YourStrongPassword!を任意のパスワードに置き換えてください。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword!';
このコマンドは、localhostからの接続時にrootユーザーのパスワードを設定します。コマンドが成功したことを確認する以下の出力が表示されるはずです。
Query OK, 0 rows affected (0.01 sec)
次に、FLUSH PRIVILEGESコマンドを使用して、権限の変更を直ちに適用します。
FLUSH PRIVILEGES;
出力は以下のようになります。
Query OK, 0 rows affected (0.00 sec)
これで、rootユーザーのパスワードを正常に設定しました。引き続きsudo mysql -u rootで接続できますが、mysql -u root -pで直接接続しようとすると、今設定したパスワードが要求されるようになります。これは、データベースを保護するための重要な最初のステップです。
rootアカウントは無制限の権限を持つため、アプリケーションでの使用はセキュリティリスクとなります。ベストプラクティスとして、各アプリケーションごとに限定された権限を持つ専用ユーザーを作成することが推奨されます。このステップでは、新しいデータベースと、そのデータベースへのアクセスのみを持つユーザーを作成します。
まず、アプリケーション用の新しいデータベースを作成します。ここではapp_dbという名前にします。
CREATE DATABASE app_db;
以下の確認メッセージが表示されるはずです。
Query OK, 1 row affected (0.01 sec)
次に、アプリケーションがデータベース接続に使用する新しいユーザーを作成します。このユーザー名をapp_userとし、パスワードを割り当てます。
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'UserPassword123';
出力は以下のようになります。
Query OK, 0 rows affected (0.01 sec)
次に、app_userに必要な権限を付与します。この例では、app_dbデータベース内のすべてのテーブルに対するSELECTおよびINSERT権限を付与します。これは最小権限の原則に従い、ユーザーが必要とする権限のみを与えます。
GRANT SELECT, INSERT ON app_db.* TO 'app_user'@'localhost';
権限をフラッシュして変更を適用します。
FLUSH PRIVILEGES;
付与した権限は、以下のコマンドで確認できます。
SHOW GRANTS FOR 'app_user'@'localhost';
出力には、app_userの正確な権限が表示されます。
+------------------------------------------------------------------+
| Grants for app_user@localhost |
+------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_user`@`localhost` |
| GRANT SELECT, INSERT ON `app_db`.* TO `app_user`@`localhost` |
+------------------------------------------------------------------+
2 rows in set (0.00 sec)
これで、適切な権限を持つ専用のデータベースとユーザーを正常に作成しました。
アプリケーションの要件は変更される可能性があり、それに応じてユーザー権限を調整する必要が生じることがあります。このステップでは、app_userから既存の権限を剥奪することで、権限の変更を練習します。
ここでは、app_userがデータ読み取り(SELECT)のみ可能で、新しいデータの追加(INSERT)はできなくなったと仮定します。INSERT権限を剥奪する必要があります。
REVOKEステートメントを使用して、app_dbデータベースに対するapp_userのINSERT権限を削除します。
REVOKE INSERT ON app_db.* FROM 'app_user'@'localhost';
以下の確認メッセージが表示されます。
Query OK, 0 rows affected (0.00 sec)
権限をフラッシュして変更を適用します。
FLUSH PRIVILEGES;
次に、ユーザーの権限を再度確認して、権限が剥奪されたことを検証します。
SHOW GRANTS FOR 'app_user'@'localhost';
出力には、app_userがapp_dbに対してSELECT権限のみを持つことが示されるはずです。INSERT権限はなくなっています。
+--------------------------------------------------------------+
| Grants for app_user@localhost |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_user`@`localhost` |
| GRANT SELECT ON `app_db`.* TO `app_user`@`localhost` |
+--------------------------------------------------------------+
2 rows in set (0.00 sec)
これにより、変化するセキュリティ要件に適応するために、ユーザー権限を効果的に管理する方法を示すことができます。
デフォルトでは、一部の MySQL インストールでは、ユーザー名が空の匿名ユーザーアカウントが作成されます。これらのアカウントは、不正アクセスを許可する可能性があるため、セキュリティリスクとなります。存在する場合は、確認して削除することが重要なセキュリティ対策です。
匿名ユーザーは、mysql.userテーブルをクエリして、ユーザー名が空のエントリを検索することで特定できます。
SELECT User, Host FROM mysql.user WHERE User = '';
匿名ユーザーが存在する場合、このクエリはそれらをリスト表示します。Ubuntu でのクリーンインストールには含まれている場合がありますが、新しいバージョンの MySQL/MariaDB ではデフォルトで匿名ユーザーが含まれていないことがよくあります。
以下のような結果が表示された場合:
+------+-----------+
| User | Host |
+------+-----------+
| | localhost |
+------+-----------+
1 row in set (0.00 sec)
その場合は、ユーザー名(空文字列 '')とホストを指定して、DROP USERステートメントで匿名ユーザーを削除する必要があります。
DROP USER ''@'localhost';
以下の確認メッセージが表示されるはずです。
Query OK, 0 rows affected (0.01 sec)
ただし、クエリが以下のような空セットを返す場合:
Empty set (0.00 sec)
これは、データベースに匿名ユーザーが存在しないことを意味し、既に安全な状態です。この場合、存在しない匿名ユーザーを削除しようとすると、エラーが発生します。
ERROR 1396 (HY000): Operation DROP USER failed for ''@'localhost'
匿名ユーザーが存在しない場合にこのエラーが発生するのは想定内であり、安全に続行できます。
匿名ユーザーを確認し、必要に応じて削除した後、権限をフラッシュして、変更が適用されていることを確認します。
FLUSH PRIVILEGES;
SELECTクエリを実行して、匿名ユーザーが残っていないことを再度確認します。
SELECT User, Host FROM mysql.user WHERE User = '';
このクエリは空セットを返し、匿名ユーザーが存在しないことを確認する必要があります。
Empty set (0.00 sec)
これで、サーバーからの潜在的なセキュリティ脆弱性を正常に確認し、対処しました。MySQL シェルを終了できます。
exit;
この実験では、いくつかの重要な MySQL のセキュリティベストプラクティスを学び、実践しました。rootアカウントにパスワードを設定して保護し、最小権限の原則に基づいた限定的な権限を持つ専用のアプリケーションユーザーを作成し、権限を剥奪してユーザーアクセスを管理し、潜在的な匿名ユーザーアカウントを確認して対処しました。
これらの基本的なセキュリティ対策を実装することで、MySQL データベースのセキュリティ体制を大幅に向上させ、不正アクセスや潜在的な脅威から保護することができます。