MySQL密码安全
主要是涉及,账号密码安全策略方面
valitdate_password、connect-control、密码过期等。
(1)MySQL资源限制:
通过设置全局变量max_user_connections可以限制单个用户在同一时间连接MySQL实例的数量,但此参数无法对每个用户区别对待,所以MySQL提供了对每个用户的资源限制管理。max_connections是所有用户的连接数量
MAX_QUERIES_PER_HOUR:一个用户在一个小时内可以执行查询的次数(基本包含所有语句)
MAX_UPDATES_PER_HOUR:一个用户在一个小时内可以执行修改的次数(仅包含修改数据库或表的语句)
MAX_CONNECTIONS_PER_HOUR:一个用户在一个小时内可以连接MySQL的时间
MAX_USER_CONNECTIONS:一个用户可以在同一时间连接MySQL实例的数量
使用方法:
CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'
WITH MAX_QUERIES_PER_HOUR 200
MAX_UPDATES_PER_HOUR 100
MAX_CONNECTIONS_PER_HOUR 20
MAX_USER_CONNECTIONS 20;
如果只修改某一个限制:
CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank' WITH MAX_QUERIES_PER_HOUR 200;
该语句仅修改指定的限额值,其余部分保持不变。若要删除限制,请将其值设置为零。
(2)MySQL用户密码过期策略
设置系统参数default_password_lifetime作用于所有的用户账户。
default_password_lifetime=180 设置180天过期
default_password_lifetime=0 设置密码不过期
如果为每个用户设置了密码过期策略,则会覆盖上述系统参数
ALTER USER 'xxx'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;设置90天过期
ALTER USER 'xxx'@'localhost' PASSWORD EXPIRE NEVER; 密码不过期
ALTER USER 'xxx'@'localhost' PASSWORD EXPIRE DEFAULT; 默认过期策略
手动强制某个用户密码过期
ALTER USER 'xxx'@'localhost' PASSWORD EXPIRE;
手动让用户账号锁定,无法登陆:
alter user xxx@'localhost' account lock;
alter user xxx@'localhost' account unlock;
(3)自定义密码策略
MySQL 5.7版本以及MySQL 8.0版本 支持通过validate_password插件修改数据库账号的密码复杂度校验规则:
密码和账号名是否可以一致。
密码的长度。
密码中需包含的大小写字母个数。
密码中需包含的数字个数。
密码中需包含的特殊字符个数。
密码检测强度。
检查是否安装
SELECT PLUGIN_NAME, PLUGIN_LIBRARY, PLUGIN_STATUS, LOAD_OPTION FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME = 'validate_password';
在线安装:
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
UNINSTALL PLUGIN validate_password;
安装组件(8.0)
INSTALL COMPONENT 'file://component_validate_password';
UNINSTALL COMPONENT 'file://component_validate_password';
在参数文件my.cnf中添加参数。
[mysqld]
plugin-load-add=validate_password.so
#ON/OFF/FORCE/FORCE_PLUS_PERMANENT: 是否使用该插件(及强制/永久强制使用)
validate-password=FORCE_PLUS_PERMANENT #参数FORCE_PLUS_PERMANENT是为了防止插件在MySQL运行时的时候被卸载
查看插件相关的系统变量,如下所示:
mysql> show variables like 'validate_password%';
+---------------------------------------------------------+--------+
| 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)
选项 默认值 参数描述
validate_password_check_user_name ON 设置为ON的时候表示能将密码设置成当前用户名。
validate_password_dictionary_file 用于检查密码的字典文件的路径名,默认为空
validate_password_length 8 密码的最小长度,也就是说密码长度必须大于或等于8
validate_password_mixed_case_count 1 如果密码策略是中等或更强的,validate_password要求密码具有的小写和大写字符的最小数量。
validate_password_number_count 1 密码必须包含的数字个数
validate_password_policy MEDIUM 密码强度检验等级,可以使用数值0、1、2或相应的符号值LOW、MEDIUM、STRONG来指定。
0/LOW:只检查长度。
1/MEDIUM:检查长度、数字、大小写、特殊字符。
2/STRONG:检查长度、数字、大小写、特殊字符、字典文件。
validate_password_special_char_count 1 密码必须包含的特殊字符个数
修改密码强度。#注意,如果是插件的话,SQL为set global validate_password_policy=LOW
SET GLOBAL validate_password_policy=LOW;
SET GLOBAL validate_password.policy=LOW;
函数组件去检测密码是否满足条件: 0-100,当评估在100时就是说明使用上了最基本的规则:大写+小写+特殊字符+数字组成的8位以上密码
mysql> SELECT VALIDATE_PASSWORD_STRENGTH('medium');
+--------------------------------------+
| VALIDATE_PASSWORD_STRENGTH('medium') |
+--------------------------------------+
| 25 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT VALIDATE_PASSWORD_STRENGTH('K354*45jKd5');
+-------------------------------------------+
| VALIDATE_PASSWORD_STRENGTH('K354*45jKd5') |
+-------------------------------------------+
| 100 |
+-------------------------------------------+
1 row in set (0.00 sec)
如果想要使用字典过滤弱口令的话,系统变量validate_password.policy必须为STRONG
状态:
如果是插件的话,是没有相对应的状态变量,只有组件有对应的系统变量。
mysql> show status like 'validate_pass%';
+-----------------------------------------------+---------------------+
| Variable_name | Value |
+-----------------------------------------------+---------------------+
| validate_password_dictionary_file_last_parsed | 2020-08-13 11:33:47 |
| validate_password_dictionary_file_words_count | 0 |
+-----------------------------------------------+---------------------+
2 rows in set (0.00 sec)
(4)CONNECTION_CONTROL连接控制
MySQL 5.7.17 以后提供了Connection-Control插件用来控制客户端在登录操作连续失败一定次数后的响应的延迟。
该插件可有效的防止客户端暴力登录的风险(攻击)。该插件包含以下2个组件:
CONNECTION_CONTROL:用来控制登录失败的次数及延迟响应时间
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS:该表将登录失败的操作记录至IS库中
-- 插件动态安装启用
mysql> INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
mysql> INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
-- 验证是否正常安装
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'connection%';
mysql> SHOW PLUGINS;
-- 配置文件增加以下配置
[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
connection_control_failed_connections_threshold 失败尝试的次数,默认为3,表示当连接失败3次后启用连接控制,0表示不开启
connection_control_max_connection_delay 响应延迟的最大时间,默认约25天
connection_control_min_connection_delay 响应延迟的最小时间,默认1000毫秒,1秒
-- 定制化配置
mysql> SET GLOBAL connection_control_failed_connections_threshold = 3;
mysql> SET GLOBAL connection_control_min_connection_delay = 1000;
mysql> SET GLOBAL connection_control_max_connection_delay = 86400;
select * from information_schema.connection_control_failed_login_attempts;
-- 该表记录登录失败的用户及失败次数,当用户登录成功后,登录失败的记录则会被删除。
-- 重新配置connection_control_failed_connections_threshold变量,该表记录会被删除(重置)
-- 如果使用不存在的用户登录,则该表记录用户名为空,但会记录具体登录的IP
-- 连接控制的使用次数(可用户判断是否存在暴力登录尝试)
mysql> show global status like 'Connection_control_delay_generated';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| Connection_control_delay_generated | 5 |
+------------------------------------+-------+