怎样在 MySQL 8 中管理密码策略

介绍

MySQL 是世界上最流行的开源数据库管理系统,可提供按需可扩展性、高性能、完整的工作流控制、全天候正常运行时间保证并降低拥有成本。

MySQL 8 附带细粒度的数据安全功能,包括强大的身份验证和授权功能,以保护您最重要的数据,尤其是在多用户环境中工作时。

在本指南中,您将探索 MySQL 提供的不同用户的密码管理功能,包括密码重用策略、当前密码验证策略、随机密码生成器、失败登录跟踪和临时帐户锁定。

先决条件

要测试此 MySQL 密码策略指南,请确保您具备以下条件:

一个 Ubuntu 20.04 服务器。 一个非 root 用户 sudo 特权。 MySQL 8 服务器。

1. 创建示例用户

以 root 身份登录到您的 MySQL 服务器。

$ sudo mysql -u root -p

输入 MySQL 服务器的 root 密码,然后按 ENTER 继续。 然后,发出以下命令以创建示例用户。

mysql> CREATE USER 'john'@'localhost' 
       IDENTIFIED BY 'EXAMPLE_PASSWORD';

输出:

Query OK, 0 rows affected (0.01 sec)

从 MySQL 命令行界面退出。

mysql> QUIT;

输出:

Bye

使用示例用户后,您现在将在下一步中限制使用以前的密码。

2. 管理密码重用策略

从 MySQL 8.0.13 开始,如果以前的密码已被泄露,您可以限制用户重复使用旧密码以加强安全性。

您可以通过显式设置 password_historypassword_reuse_interval MySQL 配置文件中的全局变量。

变量 password_history 确定在重复使用每个密码之前必须设置的唯一密码的数量。 然后,该 password_reuse_interval 定义重新使用旧密码所需的时间。

要设置这两个变量,请使用 nano 打开 MySQL 配置文件。

$ sudo nano /etc/mysql/my.cnf

然后,在文件中输入以下信息,允许用户在设置三个新密码后才能重复使用旧密码。 此外,限制用户重复使用过去 365 天使用过的旧密码。

...
[mysqld]
password_history=3
password_reuse_interval=365

保存并关闭文件。 然后,重新启动 MySQL 服务器以加载新配置。

$  sudo systemctl restart mysql

现在,以身份登录 MySQL 服务器 john 以测试新设置。

$ sudo mysql -u john -p

输入您的密码,然后按 ENTER 继续。 一旦你得到 mysql> 提示,尝试通过执行以下语句两次将新密码设置为当前密码。

mysql> ALTER USER 'john'@'localhost' IDENTIFIED BY 'EXAMPLE_PASSWORD';

输出。

ERROR 3638 (HY000): Cannot use these credentials for '[email protected]' because they contradict the password history policy

从 MySQL 服务器注销。

mysql> QUIT;

请注意,更改配置文件会在全局范围内建立密码重用策略。 如果您想为每个用户帐户单独设置策略,或者您可能想覆盖您在全局变量中设置的值,请​​定义 PASSWORD HISTORYPASSWORD REUSE INTERVAL 当执行 CREATE USERALTER USER 声明。

为此,请以 root 身份登录 MySQL。

$ sudo mysql -u root -p

输入您的密码,然后按 ENTER 继续。 然后,创建一个名为的新用户 mary 并设置 PASSWORD HISTORY5PASSWORD REUSE INTERVAL180 DAY.

mysql> CREATE USER 'mary'@'localhost'
       PASSWORD HISTORY 5
       PASSWORD REUSE INTERVAL 180 DAY;

输出。

Query OK, 0 rows affected (0.01 sec)

例如,要更新现有用户的密码重用策略, john,使用下面的语法。

mysql> ALTER USER 'john'@'localhost'
       PASSWORD HISTORY 5
       PASSWORD REUSE INTERVAL 180 DAY;

输出。

Query OK, 0 rows affected (0.01 sec)

上述命令应覆盖您全局设置的任何密码重用策略。 您可以通过对每个用户执行以下命令来确认每个用户的当前设置 mysql.user 桌子。

mysql> SELECT
       User, 
       Password_reuse_history, 
       Password_reuse_time 
       FROM mysql.user;

输出。

+------------------+------------------------+---------------------+
| User             | Password_reuse_history | Password_reuse_time |
+------------------+------------------------+---------------------+
...
| john             |                      5 |                 180 |
| mary             |                      5 |                 180 |
...
+------------------+------------------------+---------------------+
9 rows in set (0.00 sec)

退出 MySQL 服务器。

mysql> QUIT;

在限制重复使用最旧的密码后,您现在将配置一个要求密码在给定时间后过期的策略。

3. 管理密码过期策略

您可以将 MySQL 服务器设置为要求用户定期更改密码。 每个用户都需要在设定的时间段(例如 90 天)后更改其密码。

为了跟踪过期的密码,MySQL 维护一个时间戳,指示用户上次更改密码的时间。 因此,当用户使用比其允许的生命周期更旧的密码连接到 MySQL 服务器时,他们必须更新它。

要全局设置密码过期策略,请定义一个 default_password_lifetime 变量并将其值设置为密码在 MySQL 配置文件中应该持续的天数。

使用打开 MySQL 配置文件 nano.

$ sudo nano /etc/mysql/my.cnf

然后,在文件中输入以下信息以允许密码过期 90 天。

...
[mysqld]   
default_password_lifetime=90

如果要建立允许密码永不过期的策略,请设置 default_password_lifetime0.

...
[mysqld]   
default_password_lifetime=0

保存并关闭文件。 然后重新启动 MySQL 以加载新的更改。

$  sudo systemctl restart mysql

您可以通过定义一个 PASSWORD EXPIRE 执行时的选项 CREATE USERALTER USER 声明。

要为每个用户进行设置,请以 root 身份登录 MySQL。

$ sudo mysql -u root -p

输入您的 root 密码并按 ENTER 继续。 然后,创建一个名为的用户 smith 密码过期策略为 90 天,执行下面的语句。

mysql> CREATE USER 'smith'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

输出。

Query OK, 0 rows affected (0.01 sec)

要使用永不过期的密码创建相同的用户,请执行以下命令。

mysql> CREATE USER 'smith'@'localhost' PASSWORD EXPIRE NEVER;

输出。

Query OK, 0 rows affected (0.01 sec)

要更改 MySQL 服务器上现有用户的密码过期策略,请使用 ALTER USER 陈述。 例如,更改 PASSWORD EXPIRE INTERVAL 为用户 john365 天通过执行下面的命令。

mysql> ALTER USER 'john'@'localhost' PASSWORD EXPIRE INTERVAL 365 DAY;

要禁用密码过期策略,请使用以下命令。

mysql> ALTER USER 'john'@'localhost' PASSWORD EXPIRE NEVER;

输出。

Query OK, 0 rows affected (0.00 sec)

您还可以使用 PASSWORD EXPIRE 在一个选项 ALTER USER 陈述。 例如,执行下面的命令来标记 john's 密码已过期。

mysql> ALTER USER 'john'@'localhost' PASSWORD EXPIRE;

一旦密码手动或自动过期,您必须在下次登录 MySQL 服务器时重置它。 如果您在重置之前执行任何命令,您将收到以下错误。

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

要将您的密码重置为非特权用户,请使用目标用户帐户登录到您的 MySQL 服务器并执行以下语句。 代替 john'@'localhost 使用正确的用户名和 EXAMPLE_PASSWORD_2 具有很强的价值。

mysql> ALTER USER 'john'@'localhost' IDENTIFIED BY 'EXAMPLE_PASSWORD_2';

作为 root 用户,您可以通过对以下语句执行以下语句来确认每个用户的当前密码到期状态 mysql.user 桌子。

mysql> SELECT
       User,  
       password_expired 
       FROM mysql.user;

输出。

+------------------+------------------+
| User             | password_expired |
+------------------+------------------+
...
| john             | N                |
| mary             | N                |
| smith            | N                |
| smith2           | N                |
+------------------+------------------+
11 rows in set (0.00 sec)

退出 MySQL 服务器。

mysql> QUIT;

您现在已将 MySQL 密码定义为按要求过期。 接下来,您将探索一个 MySQL 策略,该策略要求用户在更改密码之前确认其当前密码。

4. 更改当前密码验证策略

从 MySQL 8.0.13 开始,您可以强制非特权用户在更改其帐户密码时提供其当前密码。

此选项限制可能劫持 MySQL 用户会话的任何人更改其密码,除非他们知道正确的凭据。 默认情况下,此功能处于禁用状态,您必须全局或单独打开它。

要全局启用密码验证功能,请打开 MySQL 配置文件。

$ sudo nano /etc/mysql/my.cnf

然后,在文件中输入以下信息。

...
[mysqld]   
password_require_current=ON

保存并关闭文件。 然后重启MySQL服务器。

$  sudo systemctl restart mysql

您现在已启用 password_require_current 全球。 要允许对单个用户进行密码验证,请使用 PASSWORD REQUIRE CURRENT 执行时的选项 CREATE USERALTER USER 声明。 个人帐户的设置会覆盖全局设置。 要设置它,首先,以 root 身份登录 MySQL 服务器。

$ sudo mysql -u root -p

输入您的密码,然后按 ENTER 继续。 然后,定义一个名为的用户 jamespassword verification-required policy 启用使用 PASSWORD REQUIRE CURRENT 选项。

mysql> CREATE USER 'james'@'localhost' 
       IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD' 
       PASSWORD REQUIRE CURRENT;

输出。

Query OK, 0 rows affected (0.00 sec)

要禁用 password verification-required policy 例如,在创建新用户时, roe, 使用 PASSWORD REQUIRE OPTIONAL 选项。

mysql> CREATE USER 'roe'@'localhost' 
       IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD' 
       PASSWORD REQUIRE CURRENT OPTIONAL;

输出。

Query OK, 0 rows affected (0.00 sec)

对于现有用户,请使用以下命令启用或禁用 require-current-password 政策。

关闭 password verification-required 政策 OFF 为用户 james.

mysql> ALTER USER 'james'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;

输出。

Query OK, 0 rows affected (0.01 sec)

关闭 password verification-required 政策 ON 为用户 james.

mysql> ALTER USER 'james'@'localhost' PASSWORD REQUIRE CURRENT;

输出。

Query OK, 0 rows affected (0.01 sec)

退出 MySQL 服务器。

mysql> QUIT;

现在,以用户身份登录 MySQL 服务器 james.

$ sudo mysql -u james -p

输入用户密码 james 并按 ENTER 继续。 现在,尝试更改用户的当前密码 james 通过执行下面的语句。

mysql> ALTER USER 'james'@'localhost' IDENTIFIED BY 'NEW_PASSWORD';

由于您需要输入当前密码,因此您应该会收到以下错误消息。

ERROR 3892 (HY000): Current password needs to be specified in the REPLACE clause to change it.

尝试使用 REPLACE 选项。

mysql> ALTER USER 'james'@'localhost' IDENTIFIED BY 'NEW_PASSWORD' REPLACE 'WRONG_OLD_PASSWORD';

同样,该命令将失败并显示 incorrect current password 错误。

ERROR 3891 (HY000): Incorrect current password. Specify the correct password which has to be replaced.

这次使用正确的当前密码执行语句。

mysql> ALTER USER 'james'@'localhost' IDENTIFIED BY 'NEW_PASSWORD' REPLACE 'EXAMPLE_PASSWORD';

当您的密码更改成功时,您应该得到以下输出。

Query OK, 0 rows affected (0.01 sec)

退出 MySQL 服务器。

mysql> QUIT;

密码验证现在按预期工作。 接下来,您将使用 MySQL 为新帐户和现有帐户生成强密码。

5. 使用随机密码生成器

从 MySQL 8.0.18 开始,您可以使用内置的随机密码生成器为用户生成强密码。 默认情况下,生成的密码长度为 20 个字符,由 generated_random_password_length 系统变量,范围为 5 到 255 个字符。

要测试密码生成器,请以 root 身份登录 MySQL 服务器。

$ sudo mysql -u root -p

然后,输入您的密码并按 ENTER 继续。 接下来,执行下面的命令来创建一个名为的用户 peter 带有随机密码。

mysql> CREATE USER 'peter'@'localhost' 
       IDENTIFIED BY RANDOM PASSWORD;

MySQL 创建用户并显示生成的密码如下。

+-------+-----------+----------------------+
| user  | host      | generated password   |
+-------+-----------+----------------------+
| peter | localhost | 8<_[*:[email protected];/y |
+-------+-----------+----------------------+
1 row in set (0.01 sec)

要更改用户的密码,请使用以下语法。

mysql> ALTER USER 'peter'@'localhost' IDENTIFIED BY RANDOM PASSWORD;

用户的登录凭据 peter 应更新并显示如下。

+-------+-----------+----------------------+
| user  | host      | generated password   |
+-------+-----------+----------------------+
| peter | localhost | 5L+DT;W2Fq!YQAQDku,* |
+-------+-----------+----------------------+
1 row in set (0.01 sec) 

接下来,您将设置 MySQL 以跟踪失败的登录尝试,并暂时或永久禁止使用错误凭据连接到服务器的用户帐户。

6.启用失败登录跟踪和临时锁定帐户

从 MySQL 8.0.19 开始,您可以启用失败登录跟踪并临时锁定违反规则的帐户。 例如,当客户端在尝试连接时未能提供正确的密码时,您可以将其帐户锁定几天或永久禁用它,直到您将其解锁。

要对此进行测试,请创建一个名为的用户 bob 并定义 FAILED_LOGIN_ATTEMPTS3. 另外,设置 PASSWORD_LOCK_TIME3. 简单来说,下面的语句锁定 bob's3 几天后 3 登录失败。

mysql> CREATE USER 'bob'@'localhost' 
       IDENTIFIED BY 'EXAMPLE_PASSWORD'
       FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;

输出。

Query OK, 0 rows affected (0.00 sec)

要更改现有帐户的设置,请使用以下语法。

mysql> ALTER USER 'bob'@'localhost'
       FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 10;

要在违反设置的失败登录尝试时完全锁定帐户,请设置 PASSWORD_LOCK_TIMEUNBOUNDED.

mysql> ALTER USER 'bob'@'localhost'
       FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME UNBOUNDED;

接下来,在一个新的会话中,尝试登录 bob 证书。

$ mysql -u bob -p

使用一些错误的密码重复登录过程,直到出现以下错误。

Access denied for user 'bob'@'localhost' (using password: YES)
...
ERROR 3955 (HY000): Access denied for user 'bob'@'localhost'. Account is blocked for unlimited day(s) (unlimited day(s) remaining) due to 3 consecutive failed logins.

该错误表明该用户的帐户已被锁定。

结论

在本教程中,您通过对以前密码的重用设置严格的规则来加强 MySQL 用户帐户的安全性。

您还启用了密码过期、密码验证策略并使用 MySQL 内置的随机密码生成器来设置强密码。

最后,您可以跟踪和锁定违反定义的失败登录的帐户。 使用本指南中的知识来保护 MySQL 项目中最关键的数据。

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com