Documentation Home

2.10.4 保护初始 MySQL 帐户

MySQL 安装过程涉及初始化数据目录,包括 mysql系统数据库中定义 MySQL 帐户的授权表。有关详细信息,请参阅 第 2.10.1 节,“初始化数据目录”

本节介绍如何为在 MySQL 安装过程中创建的初始帐户分配密码(如果您尚未这样做)。

授权表mysql.user定义了初始 MySQL 用户帐户及其访问权限:

  • 有些帐户有用户名root。这些是拥有所有权限并且可以执行任何操作的超级用户帐户。如果这些帐户的密码为空,则任何人都可以像没有密码root一样连接到 MySQL 服务器 并获得所有权限。 root

    • 在 Windows 上,root创建的帐户仅允许来自本地主机的连接。可以通过指定主机名 localhost、IP 地址 127.0.0.1或 IPv6 地址来 建立连接::1。如果用户在安装过程中选择了 从远程计算机启用根访问选项,Windows 安装程序将创建另一个root 允许从任何主机进行连接的帐户。

    • 在 Unix 上,每个root帐户都允许来自本地主机的连接。可以通过指定主机名localhost、IP 地址127.0.0.1、IPv6 地址::1或实际主机名或 IP 地址来建立连接。

    连接到主机的尝试127.0.0.1 通常会解析为该localhost帐户。但是,如果服务器在 skip_name_resolve启用的情况下运行,这将失败,因此该127.0.0.1帐户在这种情况下很有用。该::1帐户用于 IPv6 连接。

  • 如果为匿名用户创建了帐户,则这些帐户的用户名为空。匿名帐户没有密码,因此任何人都可以使用它们连接到 MySQL 服务器。

    • 在 Windows 上,有一个匿名帐户允许来自本地主机的连接。可以通过指定主机名来建立连接localhost

    • 在 Unix 上,每个匿名帐户都允许来自本地主机的连接。可以通过为其中一个帐户指定主机名或localhost为另一个帐户指定实际主机名或 IP 地址来建立连接。

    • 该帐户在表中 'root'@'localhost'还有一行,可以为 授予权限 ,即为所有用户和所有主机授予权限。这可以设置代理用户,以及将设置代理用户的权限委托给其他帐户。请参阅 第 6.2.12 节,“代理用户”mysql.proxies_privPROXY''@''root

要显示系统表中存在哪些帐户 mysql.user并检查其密码是否为空,请使用以下语句:

mysql> SELECT User, Host, Password FROM mysql.user;
+------+--------------------+----------+
| User | Host               | Password |
+------+--------------------+----------+
| root | localhost          |          |
| root | myhost.example.com |          |
| root | 127.0.0.1          |          |
| root | ::1                |          |
|      | localhost          |          |
|      | myhost.example.com |          |
+------+--------------------+----------+

此输出表明有多个 root匿名用户帐户,其中没有一个有密码。输出在您的系统上可能不同,但是存在密码为空的帐户意味着您的 MySQL 安装不受保护,直到您采取一些措施:

  • root 为每个没有 密码的 MySQL 帐户分配一个密码。

  • 要防止客户端在没有密码的情况下以匿名用户身份连接,请为每个匿名帐户分配一个密码或删除这些帐户。

此外,该mysql.db表包含允许所有帐户访问test 数据库和名称以 开头的其他数据库的 行test_。即使对于没有特殊权限的帐户(如默认匿名帐户)也是如此。这对于测试来说很方便,但在生产服务器上是不可取的。希望数据库访问仅限于具有为此目的明确授予权限的帐户的管理员应该删除这些 mysql.db表行。

以下说明描述了如何为初始 MySQL 帐户设置密码,首先是root 帐户,然后是匿名帐户。这些说明还包括如何删除匿名帐户,如果您根本不想允许匿名访问,并描述如何删除对测试数据库的允许访问。将 new_password示例中的密码替换为您要使用的密码。替换 host_name为服务器主机的名称。SELECT您可以从前面语句的输出中确定此名称 。对于显示的输出,host_namemyhost.example.com

您不需要删除 mysql.proxies_priv表中用于支持代理用户的匿名条目。请参阅第 6.2.12 节,“代理用户”

笔记

有关设置密码的其他信息,请参阅 第 6.2.9 节“分配帐户密码”。如果您 root在设置密码后忘记了密码,请参阅 第 B.3.3.2 节“如何重置 Root 密码”

要设置其他帐户,请参阅 第 6.2.7 节,“添加帐户、分配权限和删除帐户”

您可能希望将密码设置推迟到以后,以避免在执行其他设置或测试时需要指定它们。但是,请务必在将安装用于生产目的之前设置它们。

笔记

执行本节中描述的过程的替代方法:

分配根帐户密码

root可以通过多种方式设置帐户密码 。以下讨论演示了三种方法:

要使用 分配密码SET PASSWORD,请连接到服务器 并为系统表中 列出的每个帐户root发出一条语句。SET PASSWORDrootmysql.user

对于 Windows,请执行以下操作:

$> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'::1' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'%' = PASSWORD('new_password');

如果该 mysql.user表没有 root主机值为 的帐户,则最后一条语句是不必要的 %

对于 Unix,执行此操作:

$> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'::1' = PASSWORD('new_password');
mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('new_password');

您还可以使用一条语句为所有root帐户分配密码,方法 是直接UPDATE修改 mysql.user表。此方法适用于任何平台:

$> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('new_password')
    ->     WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

FLUSH语句使服务器重新读取授权表。没有它,密码更改将不会被服务器注意到,直到您重新启动它。

要使用mysqladminroot为帐户分配密码,请执行以下命令:

$> mysqladmin -u root password "new_password"
$> mysqladmin -u root -h host_name password "new_password"

这些命令适用于 Windows 和 Unix。密码周围的双引号并不总是必需的,但如果密码包含空格或其他对您的命令解释器来说特殊的字符,您应该使用它们。

设置帐户密码的mysqladmin方法对 或 帐户root不起作用 。使用 前面显示的方法。 'root'@'127.0.0.1''root'@'::1'SET PASSWORD

设置密码后,无论何时连接到服务器root,都必须提供适当的密码 。root例如,要关闭带有mysqladmin的服务器,请使用以下命令:

$> mysqladmin -u root -p shutdown
Enter password: (enter root password here)

以下说明中的mysql命令包含一个-p选项,前提是您已root 使用前面的说明分配了帐户密码,并且在连接到服务器时必须指定该密码。

分配匿名帐户密码

要为匿名帐户分配密码,请以 身份连接到服务器root,然后使用 SET PASSWORDUPDATE

SET PASSWORD在 Windows 上使用,请执行以下操作:

$> mysql -u root -p
Enter password: (enter root password here)
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('new_password');

SET PASSWORD在 Unix 上使用,请执行以下操作:

$> mysql -u root -p
Enter password: (enter root password here)
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('new_password');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('new_password');

要使用单个 UPDATE语句设置匿名用户帐户密码,请执行以下操作(在任何平台上):

$> mysql -u root -p
Enter password: (enter root password here)
mysql> UPDATE mysql.user SET Password = PASSWORD('new_password')
    ->     WHERE User = '';
mysql> FLUSH PRIVILEGES;

FLUSH语句使服务器重新读取授权表。没有它,密码更改将不会被服务器注意到,直到您重新启动它。

删除匿名帐户

如果您更愿意删除任何匿名帐户而不是为其分配密码,请在 Windows 上执行以下操作:

$> mysql -u root -p
Enter password: (enter root password here)
mysql> DROP USER ''@'localhost';

在 Unix 上,像这样删除匿名帐户:

$> mysql -u root -p
Enter password: (enter root password here)
mysql> DROP USER ''@'localhost';
mysql> DROP USER ''@'host_name';

保护测试数据库

默认情况下,该mysql.db表包含允许任何用户访问test 数据库和名称以 . 开头的其他数据库的 行test_。(这些行有一个空 User列值,出于访问检查目的匹配任何用户名。)这意味着即使没有其他权限的帐户也可以使用此类数据库。如果要删除对测试数据库的任何用户访问权限,请按以下步骤操作:

$> mysql -u root -p
Enter password: (enter root password here)
mysql> DELETE FROM mysql.db WHERE Db LIKE 'test%';
mysql> FLUSH PRIVILEGES;

FLUSH语句使服务器重新读取授权表。没有它,服务器将不会注意到权限更改,直到您重新启动它。

通过上述更改,只有拥有全局数据库权限或明确授予数据库权限的用户 test才能使用它。但是,如果您希望数据库根本不存在,请将其删除:

mysql> DROP DATABASE test;