MySQL基础4——MySQL密码复杂度与密码过期策略
本文最后更新于 523 天前,如有失效请评论区留言。

前言

在对MySQL数据库管理的过程当中,我们会期望把数据库的密码复杂度设置得高一些,尤其是针对管理员用户root,针对数据库用户的安全而言,一般会关心密码复杂度设置,是否定期修改密码,本篇将对这两项进行展开。

密码复杂度策略

validate_passwd是MySQL自带的用于验证密码强度的插件,在MySQL的管理中,我们应该启用该插件进行密码安全管理,它可以禁止我们设置如123456这样的简单密码,有了这样的插件协助,可以确保我们每一次设置密码都具备较高复杂度,更好地保障数据库的安全。我们先来看一下MySQL都自带了哪些插件,又安装了哪些插件。

查看MySQL插件

1、登录MySQL,查询已经安装了哪些插件(MySQL自带了一些插件,不过并没有全部安装)。

mysql> show plugins;
+----------------------------------+----------+--------------------+----------------------+---------+
| Name                             | Status   | Type               | Library              | License |
+----------------------------------+----------+--------------------+----------------------+---------+
| binlog                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| sha256_password                  | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| caching_sha2_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha2_cache_cleaner               | ACTIVE   | AUDIT              | NULL                 | GPL     |
| daemon_keyring_proxy_plugin      | ACTIVE   | DAEMON             | NULL                 | GPL     |
......

我这里查不到validate_passwd的相关信息,说明默认没有安装。另外,可以从插件的状态看出插件是否启用,是ACTIVE说明已经启用,而DISABLED说明没有启用。

2、从MySQL存放插件包的目录下查看下载了哪些插件。

  • 找到插件的存放目录
mysql> show variables like '%plugin_dir%';
+---------------+----------------------------------------+
| Variable_name | Value                                  |
+---------------+----------------------------------------+
| plugin_dir    | /usr/local/appserver/mysql/lib/plugin/ |
+---------------+----------------------------------------+
1 row in set (0.00 sec)

查看该目录下的文件,可以看到MySQL自带下载了validate_password.so插件,我们只需要安装启用就可以了。

image-20240725113836868

安装validate_passwd插件

MySQL默认下载了validate_passwd插件,我们可以通过命令查看该插件是否安装(为Empty说明未安装此插件)。

mysql> show variables like 'validate%';
Empty set (0.00 sec)

执行以下命令安装validate_passwd插件(推荐通过这种方式安装插件,这样可以避免重启mysql)。

  • 通过INSTALL PLUGIN命令安装插件
  • 注意后缀,取我们查询到plugin目录中的插件名。
mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';
Query OK, 0 rows affected, 1 warning (0.02 sec)

再次查看,可以查询到validate_passwd插件的相关配置信息了。

mysql> show variables like 'validate%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | ON     |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.00 sec)

注意:也可以通过在my.cnf添加导入配置来安装插件,不过更改配置需要重启MySQL。

# vim my.cnf
[mysqld]
plugin-load = validate_password.so

密码强度相关参数解释

  1. validate_password_policy:配置密码的严格程度。
    • 0 / LOW:仅需符合密码长度(由参数validate_password_length指定);
    • 1 / MEDIUM:满足LOW策略,同时还需要满足至少一个数字、小写字母、大写字母和特殊字符;
    • 2 / STRONG:满足MEDIUM策略,同时密码不能存在字典文件里(dictionary file)。
  2. validate_password_dictionary_file:用于配置密码字典。
    • 当validate_password_policy的值设置为STRONG时可以配置密码字典,字典文件中存在的密码不得使用。
  3. validate_password_length:设置密码最小长度,默认值为8。
  4. validate_password_mixed_case_count:
    • 当validate_password_policy的值设置为MEDIUM或者STRONG时,设置密码中同时拥有的大小写字母的最小数量。默认值是1,至少需要设置一个大写和一个小写字母,该值最小可以设置为0。
  5. validate_password_number_count:
    • 当validate_password_policy的值设置为MEDIUM或者STRONG时,设置密码中拥有数字的最小数量,默认值是1,至少设置一个数字,该值最小可以设置为0。
  6. validate_password_special_char_count:
    • 当validate_password_policy的值设置为MEDIUM或者STRONG时,设置密码中的特殊字符最小数量,默认值是1,至少设置一个特殊字符,该值最小可以设置为0。

密码复杂度设置

我们可以更改上述密码强度相关参数,来修改设置密码的复杂度策略。有临时设置和永久设置两种方式,接下来依次介绍。

临时设置

可以用set命令对密码强度相关参数进行临时设置,在MySQL重启后会恢复成默认值。示例如下:

mysql> set global validate_password_length = 10;
Query OK, 0 rows affected (0.00 sec)

查询密码强度配置信息,可以看到密码长度已经变成了最少要求10位。

mysql> show variables like 'validate%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | ON     |
| validate_password_dictionary_file    |        |
| validate_password_length             | 10     |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.00 sec)

永久设置

在MySQL的配置文件my.cnf中写入密码强度参数配置,实现永久生效。以下示例:

# vim my.cnf
[mysqld]
plugin-load = validate_password.so
validate_password_length = 10
validate_password_policy = 1
validate-password = FORCE_PLUS_PERMANENT

测试密码复杂度

密码复杂度策略更改生效以后,已有的用户密码不受影响,但如果后续要更改密码,创建用户设置密码就必须满足复杂度策略的要求了。下面看看密码复杂度策略的效果。

1、新建用户设置密码。

  • 可以看到,密码长度要求最少10位以上,要包含大小写字母和特殊字符。
mysql> create user 'cuckoo'@'%' identified by '123';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> create user 'cuckoo'@'%' identified by 'Ab123';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> create user 'cuckoo'@'%' identified by 'Ab@123';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> create user 'cuckoo'@'%' identified by 'Ab@1234567';
Query OK, 0 rows affected (0.07 sec)

2、更改密码。

  • 可以看到,更改密码也严格按照我们设置的密码复杂度进行限制。
mysql> alter user 'cuckoo'@'%' identified by 'abc1234567';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> alter user 'cuckoo'@'%' identified by 'Abc@1234567';
Query OK, 0 rows affected (0.04 sec)

扩展:关闭内置插件和卸载插件

1、关闭内置插件

例子:关闭MRG_MYISAM插件,MYISAMinnodb一样,是MySQL的存储引擎之一。

# vim my.cnf 
[mysqld]
MRG_MYISAM=OFF

重启MySQL生效:

# systemctl restart mysqld

2、卸载插件

msyql> uninstall plugin rpl_semi_sync_slave;

密码过期策略

除了设置密码复杂度,我们还可以设置密码过期策略,比如说隔90天过期一次,必须修改密码才能继续使用,这样我们的数据库账户就更加安全了。下面我们来看一下如何设置密码过期策略。

单个账号密码过期策略

通过 mysql.user 表查看数据库账号状态。

  • password_expired:密码过期,Y是过期,N是没有过期,默认值是N。
mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| user             | host      | password_expired | password_lifetime | password_last_changed | account_locked |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| cuckoo           | %         | N                |              NULL | 2024-07-25 12:45:07   | N              |
| mysql.infoschema | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.session    | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.sys        | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| root             | localhost | N                |              NULL | 2024-07-24 17:22:06   | N              |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
5 rows in set (0.00 sec)

1、指定用户的密码立即过期。

mysql> alter user 'cuckoo'@'%' password expire;
Query OK, 0 rows affected (0.03 sec)

mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| user             | host      | password_expired | password_lifetime | password_last_changed | account_locked |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| cuckoo           | %         | Y                |              NULL | 2024-07-25 12:45:07   | N              |
| mysql.infoschema | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.session    | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.sys        | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| root             | localhost | N                |              NULL | 2024-07-24 17:22:06   | N              |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
5 rows in set (0.00 sec)

密码过期的用户还是可以登录MySQL,但是在用户未设置新密码之前不能运行任何查询语句,而且会得到以下错误消息提示:

mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

此时用户可以执行alter命令为自己更改密码,当用户设置了新密码后,此用户的所有操作(根据用户自身的权限)会被允许执行。

mysql> alter user cuckoo@'%' identified by 'Abcd@123456';
Query OK, 0 rows affected (0.06 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.01 sec)

2、指定用户的密码永不过期。

  • 也可以用SET GLOBAL default_password_lifetime = 0;设置永不过期。
mysql> alter user 'cuckoo'@'%' password expire never;
Query OK, 0 rows affected (0.03 sec)

mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| user             | host      | password_expired | password_lifetime | password_last_changed | account_locked |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| cuckoo           | %         | Y                |                 0 | 2024-07-25 12:45:07   | N              |
| mysql.infoschema | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.session    | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.sys        | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| root             | localhost | N                |              NULL | 2024-07-24 17:22:06   | N              |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
5 rows in set (0.00 sec)

3、指定用户的密码90天后过期。

mysql> alter user 'cuckoo'@'%' password expire interval 90 day;
Query OK, 0 rows affected (0.04 sec)

mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| user             | host      | password_expired | password_lifetime | password_last_changed | account_locked |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| cuckoo           | %         | Y                |                90 | 2024-07-25 12:45:07   | N              |
| mysql.infoschema | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.session    | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.sys        | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| root             | localhost | N                |              NULL | 2024-07-24 17:22:06   | N              |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
5 rows in set (0.00 sec)

4、指定用户的密码使用数据库的默认过期策略。

mysql> alter user 'cuckoo'@'%' password expire default;
Query OK, 0 rows affected (0.03 sec)

mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| user             | host      | password_expired | password_lifetime | password_last_changed | account_locked |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
| cuckoo           | %         | Y                |              NULL | 2024-07-25 12:45:07   | N              |
| mysql.infoschema | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.session    | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| mysql.sys        | localhost | N                |              NULL | 2024-07-24 17:22:07   | Y              |
| root             | localhost | N                |              NULL | 2024-07-24 17:22:06   | N              |
+------------------+-----------+------------------+-------------------+-----------------------+----------------+
5 rows in set (0.00 sec)

全局账号密码过期策略

使用 default_password_lifetime 系统变量构建全局密码自动过期策略。在 5.7.11 版本之前,默认的 default_password_lifetime 值为 360(密码大约每年必须更改一次),之后的版本默认值为 0,表示密码不会过期。此参数的单位是天,比如我们可以将此参数设置为 90 ,则表示全局密码自动过期策略是 90 天。

通过MySQL命令行设置:

mysql> set global default_password_lifetime = 90;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'default_password_lifetime';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| default_password_lifetime | 90    |
+---------------------------+-------+
1 row in set (0.01 sec)

通过配置文件my.cnf设置

[mysqld]
default_password_lifetime = 90

小结

我们可以通过MySQL的validate_passwd插件设置用户的密码复杂度策略,并通过MySQL的password_expired特性、default_password_lifetime特性控制用户密码的过期策略,来提高MySQL的安全性。

版权声明:除特殊说明,博客文章均为cuckooyang原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。 | 博客订阅:RSS | 广告招租:留言板 | 博客VPS |
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇