一、密码复杂度策略设置

MySQL 系统自带有 validate_password 插件,此插件可以验证密码强度,未达到规定强度的密码则不允许被设置。MySQL 5.7 及 8.0 版本默认情况下貌似都不启用该插件,这也使得我们可以随意设置密码,比如设置为 123、123456等。如果我们想从根源上规范密码强度,可以启用该插件,下面一起来看下如何通过此插件来设置密码复杂度策略。

1)查看是否已安装此插件

进入 MySQL 命令行,通过 show plugins 或者查看 validate_password 相关参数可以判断是否已安装此插件。若没有相关参数则代表未安装此插件

安装前检查 为空则说明未安装此插件

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

2)安装 validate_password 插件

通过 INSTALL PLUGIN 命令可安装此插件 # 每个平台的文件名后缀都不同 对于 Unix 和类 Unix 系统,为.so,对于 Windows 为.dll

mysql> INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Query OK, 0 rows affected, 1 warning (0.28 sec)

查看 validate_password 相关参数

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)

3)密码强度相关参数解释

安装 validate_password 插件后,多了一些密码强度相关参数,这些参数从字面意思上也很容易看懂,下面简单解释下几个重点参数。

1、validate_password_policy
代表的密码策略,默认是MEDIUM 可配置的值有以下:
0 or LOW 仅需需符合密码长度(由参数validate_password_length指定)
1 or MEDIUM 满足LOW策略,同时还需满足至少有1个数字,小写字母,大写字母和特殊字符
2 or 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

4)密码复杂度策略具体设置

学习完以上参数,我们就可以根据自身情况来具体设置密码复杂度策略了,比如我想让密码至少 10 位且包含大小写字母、数字、特殊字符,则可以这样设置。

设置密码长度至少10位

mysql> set global validate_password_length = 10;
 Query OK, 0 rows affected (0.00 sec)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)

若想永久生效,建议将以下参数写入配置文件

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

5)测试密码复杂度

密码复杂度策略只对生效后的操作有效,比如说你之前有个账号,密码是 123 ,则该账号还是可以继续使用的,不过若再次更改密码则需满足复杂度策略。下面我们来测试下密码复杂度策略的具体效果。

新建用户设置密码

mysql> create user ‘testuser’@’%’ identified by ‘123’;
 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
 mysql> create user ‘testuser’@’%’ identified by ‘ab123’;
 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
 mysql> create user ‘testuser’@’%’ identified by ‘Ab@123’;
 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
 mysql> create user ‘testuser’@’%’ identified by ‘Bsdf@5467672’;
 Query OK, 0 rows affected (0.01 sec)

更改密码

mysql> alter user ‘testuser’@’%’ identified by ‘dfgf3435’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> alter user ‘testuser’@’%’ identified by ‘dBsdf@5467672’;
Query OK, 0 rows affected (0.01 sec)
2.设置密码自动过期
除了设置密码复杂度策略外,我们还可以设置密码自动过期,比如说隔 90 天密码会过期必须修改密码后才能继续使用,这样我们的数据库账号就更加安全了。下面我们来看下如何设置密码自动过期。

单独设置某个账号密码过期时间

使用 ALTER USER 语句可以使单个账号密码过期,也可以更改账号过期时间。

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

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 |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 | expuser | % | N | NULL | 2021-01-05 14:30:30 | N |
 | root | % | N | NULL | 2020-10-30 14:45:43 | N |
 | testuser | % | N | NULL | 2021-01-04 17:22:37 | N |
 | mysql.infoschema | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.session | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.sys | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | root | localhost | N | NULL | 2020-10-30 14:38:55 | N |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 7 rows in set (0.01 sec)

使 expuser 账号密码立即过期

mysql> ALTER USER ‘expuser’@’%’ PASSWORD EXPIRE;
 Query OK, 0 rows affected (0.00 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 |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 | expuser | % | Y | NULL | 2021-01-05 14:30:30 | N |
 | root | % | N | NULL | 2020-10-30 14:45:43 | N |
 | testuser | % | N | NULL | 2021-01-04 17:22:37 | N |
 | mysql.infoschema | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.session | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.sys | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | root | localhost | N | NULL | 2020-10-30 14:38:55 | N |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 7 rows in set (0.00 sec)

修改账号密码永不过期

mysql> ALTER USER ‘expuser’@’%’ PASSWORD EXPIRE NEVER;
Query OK, 0 rows affected (0.01 sec)

单独设置该账号密码90天过期

mysql> ALTER USER ‘expuser’@’%’ PASSWORD EXPIRE INTERVAL 90 DAY;
 Query OK, 0 rows affected (0.00 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 |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 | expuser | % | N | 90 | 2021-01-05 14:41:28 | N |
 | root | % | N | NULL | 2020-10-30 14:45:43 | N |
 | testuser | % | N | NULL | 2021-01-04 17:22:37 | N |
 | mysql.infoschema | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.session | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | mysql.sys | localhost | N | NULL | 2020-10-30 14:37:09 | Y |
 | root | localhost | N | NULL | 2020-10-30 14:38:55 | N |
 ±-----------------±----------±-----------------±------------------±----------------------±---------------+
 7 rows in set (0.00 sec)

让此账号使用默认的密码过期全局策略

mysql> ALTER USER ‘expuser’@’%’ PASSWORD EXPIRE DEFAULT;
Query OK, 0 rows affected (0.01 sec)
mysql.user 系统表记录着每个账号的相关信息,当 password_expired 字段值为 Y 时,代表此密码已过期,使用过期密码仍可以登录,但不能进行任何操作,进行操作会提示:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. 必须更改密码后才能进行正常操作。

对于给定过期时间的账号,比如说设置 90 天过期,数据库系统会比较当前时间与上次修改密码的时间差值,如果距离上次修改密码时间超过 90 天,则将此账号密码标记为过期,必须更改密码后才能进行操作。

设置全局过期策略

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

设置全局过期策略 先手动更改再加入配置文件

mysql> SET GLOBAL default_password_lifetime = 90;
 Query OK, 0 rows affected (0.01 sec)mysql> show variables like ‘default_password_lifetime’;
 ±--------------------------±------+
 | Variable_name | Value |
 ±--------------------------±------+
 | default_password_lifetime | 90 |
 ±--------------------------±------+
 1 row in set (0.00 sec)

写入配置文件使得重启生效

[mysqld]
default_password_lifetime = 90

二、mysql账号锁定策略

Connection-Control插件用来控制客户端在登录操作连续失败一定次数后的响应的延迟。可防止客户端暴力破解。

1)查询插件是否安装

mysql关闭密码策略命令 mysql密码安全策略_mysql关闭密码策略命令

如果有connection_control则已安装,没有则继续下一步。

2)安装插件

在mysql5.7后mysql/data/lib/plugin目录默认增加了connection_control.so插件,安装即可:

install plugin connection_control soname “connection_control.so”; #登录错误次数限制插件
install plugin connection_control_failed_login_attempts soname ‘connection_control.so’; #为了把错误次数记录到表中

3)设置插件

查询一下安装状态show variables like “%connection_control%”;

mysql关闭密码策略命令 mysql密码安全策略_ide_02

解释:

connection_control_failed_connections_threshold :连续失败最大次数3次,0表示不开启
connection_control_max_connection_delay :超过最大失败次数之后阻塞登录最大时间(毫秒)
connection_control_min_connection_delay :超过最大失败次数之后阻塞登录最小时间(毫秒)
修改配置命令:set global connection_control_failed_connections_threshold=5

4)修改my.cnf配置文件

[mysqld]
 plugin-load-add = connection_control.so
 connection-control = FORCE
 connection-control-failed-login-attempts = FORCE
 connection_control_min_connection_delay = 1000
 connection_control_max_connection_delay = 86400
 connection_control_failed_connections_threshold = 3

5)查询插件状态

show status like “%connection_control%”;

mysql关闭密码策略命令 mysql密码安全策略_复杂度_03

Connection_control_delay_generated:表示连接控制的使用次数(可用户判断是否存在暴力登录尝试)

重新配置connection_control_failed_connections_threshold变量,该表记录会被删除(重置)

SET GLOBAL connection_control_failed_connections_threshold = 3;

六、查询各账号登录失败次数

use information_schema;

select * from connection_control_failed_login_attempts;

mysql关闭密码策略命令 mysql密码安全策略_mysql关闭密码策略命令_04


如果使用不存在的用户登录,则该表记录用户名为空,但会记录具体登录的IP