介绍
在本实验中,你将学习如何增强 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 shell。
exit;
在此次实验中,你学习并应用了多项重要的 MySQL 安全最佳实践。你成功地为 root 账户设置了密码,根据最小权限原则创建了一个具有有限权限的专用应用程序用户,通过撤销权限管理了用户访问,并检查和处理了潜在的匿名用户账户。
通过实施这些基本的安全措施,你可以显著提高 MySQL 数据库的安全级别,并保护其免受未经授权的访问和潜在威胁。