怎么做海淘网站,宝山顺德网站建设,郑州市重点项目建设办公室网站,建设网站需要哪个软件这是一篇关于如何加强 MySQL 用户安全的文章#xff0c;通读全文您可以了解密码复杂度策略、连接控制插件以及密码变更策略的相关知识。本文内容仅供参考#xff0c;请在操作时以实际环境为准#xff0c;避免造成经济损失。 作者#xff1a;余振兴#xff0c;爱可生 DBA 团…这是一篇关于如何加强 MySQL 用户安全的文章通读全文您可以了解密码复杂度策略、连接控制插件以及密码变更策略的相关知识。本文内容仅供参考请在操作时以实际环境为准避免造成经济损失。 作者余振兴爱可生 DBA 团队成员热衷技术分享、编写技术文档。 作者官永强爱可生 DBA 团队成员擅长 MySQL 运维方面的技能。热爱学习新知识亦是个爱打游戏的宅男。 爱可生开源社区出品原创内容未经授权不得随意使用转载请联系小编并注明来源。 本文约 4000 字预计阅读需要 10 分钟。 背景
基于安全的背景下客户对 MySQL 的用户安全上提出了一系列需求希望能对 MySQL 进行安全加固具体的需求如下
用户密码类
密码需要至少 25 个字符 密码必须包含至少 2 个大写字母密码必须包含至少 2 个小写字母密码必须包含至少 2 个数字密码必须包含至少 2 个特殊字符密码中不能包含用户名密码不能是简单的重复字符例如AAAwuwuwuwu, dsadsadsa, 111 密码需要有过期时间需要 365 天修改一次否则过期并锁定用户密码不得使用历史 5 次内曾用过的老密码密码在 24 小时内最多只能修改一次密码不能包含指定的字符如公司名称、业务名称等用户连接类 登录时如果连续 10 次失败需要等待 10 分钟且每次失败持续增加等待时间
需求分析
基于背景描述我们可以把需求分为三大块
密码复杂度策略连接控制的策略密码变更的策略
MySQL 有以下功能插件/组件、配置可实现以上需求
密码校验插件/组件连接控制插件用户密码属性配置环境信息 MySQL 版本8.0.33、5.7.41
安装配置
1. 密码校验组件配置
MySQL 5.7 版本为密码校验插件虽然安装方式和变量有语法有些许差异但功能基本相同。以下操作仅以 MySQL 8.0 版本操作为例具体细节可参考官方文档。
## 8.0 版本安装密码校验组件
INSTALL COMPONENT file://component_validate_password;## 查看插件默认配置
show variables like validate_password%;
----------------------------------------------
| Variable_name | Value |
----------------------------------------------
| validate_password.check_user_name | ON | ## 密码不能包含用户名
| validate_password.dictionary_file | | ## 指定密码匹配字典文件在文件中的字符串不能包含在设置的密码中在 policy 为 STRONG 时有效
| validate_password.length | 8 | ## 密码最小长度默认至少 8 位长
| validate_password.mixed_case_count | 1 | ## 密码至少包含 1 个大小写字母
| validate_password.number_count | 1 | ## 密码至少包含一个数字
| validate_password.policy | MEDIUM | ## 密码默认复杂度策略
| validate_password.special_char_count | 1 | ## 密码至少包含一个特殊字符
----------------------------------------------
7 rows in set (0.0042 sec)## 修改配置以便符合背景需求
set global validate_password.length25;
set global validate_password.mixed_case_count2;
set global validate_password.number_count2;
set global validate_password.special_char_count2;## 查看调整后的配置动态生效
show variables like validate_password%;
----------------------------------------------
| Variable_name | Value |
----------------------------------------------
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 25 |
| validate_password.mixed_case_count | 2 |
| validate_password.number_count | 2 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 2 |
----------------------------------------------
7 rows in set (0.0056 sec)## 持久化配置到 my.cnf 配置文件永久生效
## 在 [mysqld] 标签下增加配置
vim /data/mysql/3306/my.cnf.3306
[mysqld]
## 密码校验组件参数配置
validate_password.check_user_name ON
validate_password.policy MEDIUM
validate_password.length 25
validate_password.mixed_case_count 2
validate_password.number_count 2
validate_password.special_char_count 2
2. 连接控制插件配置
连接控制插件在 MySQL 5.7 和 MySQL 8.0 基本无变化均以插件形式提供。以下操作仅以 MySQL 8.0 版本操作为例具体细节可参考官方文档。
## 连接控制插件安装
INSTALL PLUGIN CONNECTION_CONTROL SONAME connection_control.so;
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME connection_control.so;## 查看插件默认配置
show variables like connection_control%;
-------------------------------------------------------------
| Variable_name | Value |
-------------------------------------------------------------
| connection_control_failed_connections_threshold | 3 | ## 运行登录失败尝试的次数默认为 3表示当连接失败 3 次后启用连接控制0 表示不开启
| connection_control_max_connection_delay | 2147483647 | ## 响应延迟的最大时间默认约25天
| connection_control_min_connection_delay | 1000 | ## 登录失败后响应延迟的最小时间默认 1000 毫秒1 秒每失败一次逐步累加直到最大值
-------------------------------------------------------------## 修改配置以便符合背景需求,响应延迟的最大时间设置为 1 天
set global connection_control_max_connection_delay24*60*60*1000;## 查看调整后的配置动态生效
show variables like connection_control%;
--------------------------------------------------------
| Variable_name | Value |
--------------------------------------------------------
| connection_control_failed_connections_threshold | 3 |
| connection_control_max_connection_delay | 86400000 | ## 调整为最大一天
| connection_control_min_connection_delay | 1000 |
--------------------------------------------------------## 持久化配置到 my.cnf 配置文件永久生效
## 在 [mysqld] 标签下增加配置
vim /data/mysql/3306/my.cnf.3306
[mysqld]
## 连接控制插件配置
connection-control FORCE
connection-control-failed-login-attempts FORCE
connection_control_min_connection_delay 1000
connection_control_max_connection_delay 86400000
connection_control_failed_connections_threshold 3
3. 密码变更策略配置
MySQL 密码变更策略配置记录在 mysql.user 表中5.7 和 8.0 版本支持的配置略有差异具体细节可参考官方文档中 CREATE USER 和 ALTER USER 语法中 password_option 部分属性说明。
相关配置参数含义说明
MySQL 5.7 版本下仅支持
default_password_lifetime 密码有效期默认为 0 或 NULL表示密码永久有效。 注意线上环境配置密码过期策略虽然可提升安全性但如果没及时更新密码会导致业务中断问题需要综合评估后配置 MySQL 8.0 版本支持
default_password_lifetime密码有效期默认为 0 或 NULL表示密码永久有效。 注意线上环境配置密码过期策略虽然可提升安全性但如果没及时更新密码会导致业务中断问题需要综合评估后配置 password_history历史密码可重用的循环表示记录历史上前多少次密码不允许被重复使用历史密码信息记录在 mysql.password_history 表中。
password_reuse_interval指定历史密码要经过多长时间才能被重用单位为天。 关于 default_password_lifetime、password_history 以及 password_reuse_interval 在 my.cnf 配置后创建用户默认属性不生效的问题提了 MySQL Bug待官方反馈是否符合预期。 结论不是 Bug对参数的理解有误。 以密码过期配置为示例说明password_reuse_interval、password_history 均为相同逻辑。 ALTER USER eee PASSWORD EXPIRE; eee 用户密码立即过期mysql.user 表中 password_expired 字段标记为 Y ALTER USER eee PASSWORD EXPIRE DEFAULT; eee 用户密码过期策略采用全局参数 default_password_lifetime 指定的值作为过期策略mysql.user 表中的 password_lifetime 字段为 NULL ALTER USER eee PASSWORD EXPIRE NEVER; eee 用户密码过期策略设置为永不过期mysql.user 表中的 password_lifetime 字段值为 0 ALTER USER eee PASSWORD EXPIRE INTERVAL 3 DAY; eee 用户密码过期策略设置为指定 3 天后过期mysql.user 表中的 password_lifetime 字段值为 3 关于 password_history 和 password_reuse_interval 参数同时使用时实际只有 password_reuse_interval 参数有效的问题提了 MySQL Bug待官方反馈是否符合预期。 ################## 以5.7版本为例 ##################
## 1. 修改当前默认密码策略为需求所需配置(动态生效
set global default_password_lifetime365;## 2. 查看当前密码有效期配置。这里一定注意表中的password_lifetime为NULL不是表示无策略而是表示使用default_password_lifetime参数指定的全局策略
select user,host,password_lifetime from mysql.user where user not in (mysql.session,mysql.sys);
----------------------------------------
| user | host | password_lifetime |
----------------------------------------
| root | localhost | NULL |
| zhenxing | % | NULL |
| sysbench | % | NULL |
| aaa | % | NULL |
| bbb | % | NULL |
----------------------------------------## 3. 持久化当前默认密码策略为需求所需配置永久生效
## 在[mysqld]标签下增加配置
vim /data/mysql/3306/my.cnf.3306
[mysqld]
## 密码策略配置
default_password_lifetime 365################## 以8.0版本为例 ##################
## 1. 修改当前默认密码策略为需求所需配置(动态生效
set global default_password_lifetime365;
set global password_history5;
set global password_reuse_interval1;## 2. 查看当前已存在用户的密码策略配置默认均为NULL表示使用default_password_lifetime、password_history、password_reuse_interval参数指定的全局策略
select user,host,password_lifetime,Password_reuse_history,Password_reuse_time from mysql.user where user not in (mysql.infoschema,mysql.session,mysql.sys);
-------------------------------------------------------------------------------------
| user | host | password_lifetime | Password_reuse_history | Password_reuse_time |
-------------------------------------------------------------------------------------
| aaa | % | NULL | NULL | NULL |
| sysbench | % | NULL | NULL | NULL |
| zhenxing | % | NULL | NULL | NULL |
| backup | 127.0.0.1 | NULL | NULL | NULL |
| backup | localhost | NULL | NULL | NULL |
| root | localhost | NULL | NULL | NULL |
-------------------------------------------------------------------------------------## 3. 持久化当前默认密码策略为需求所需配置永久生效
## 在[mysqld]标签下增加配置
vim /data/mysql/3306/my.cnf.3306
[mysqld]
## 密码策略配置
default_password_lifetime 365
password_history 5
password_reuse_interval 1
功能验证
1. 密码校验组件
MySQL 5.7 版本为密码校验插件安装方式和变量有语法差异功能基本相同以下操作仅以 5.7 版本操作为例。
################## 以5.7版本为例 ##################
##1.查看当前密码校验插件配置信息
mysql show variables like validate%;
-------------------------------------------------------------
| Variable_name | Value |
-------------------------------------------------------------
| validate_password_check_user_name | ON |
| validate_password_dictionary_file | /usr/share/dict/words |
| validate_password_length | 25 |
| validate_password_mixed_case_count | 2 |
| validate_password_number_count | 2 |
| validate_password_policy | STRONG |
| validate_password_special_char_count | 2 |
-------------------------------------------------------------
7 rows in set (0.00 sec)## 2. 进行验证
## 2.1 验证密码不符合 validate_password_mixed_case_count≥2 时是否可以成功新建用户
mysql create user test33% identified WITH mysql_native_password by1234567890#$tyuiopasdfg;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements## 2.2 验证密码不符合 validate_password_number_count≥2 时是否可以成功新建用户
mysql create user test33% identified WITH mysql_native_password byqazwsxEDCRFVtgb%$#ujmnbgf;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements## 2.3 验证密码不符合 validate_password_special_char_count≥2 时是否可以成功新建用户
mysql create user test33% identified WITH mysql_native_password by1qazWSXEDCdsa321321321dsadwq;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements## 2.4 验证密码不符合 validate_password_length≥25 时是否可以成功新建用户
mysql create user test33% identified WITH mysql_native_password by123!#qazWWSX;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements## 2.5 关闭大小写字母数量验证功能验证使用的密码记录在密码字典中时2167sags$er24sfwjdtegcfaskvc是否可以成功新建用户
[root10-186-60-13 dict]# cat words
12!qwqw
12qw!qw
2167sags$er24sfwjdtegcfaskvc
mysql set global validate_password_mixed_case_count0;
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 | /usr/share/dict/words |
| validate_password_length | 25 |
| validate_password_mixed_case_count | 0 |
| validate_password_number_count | 2 |
| validate_password_policy | STRONG |
| validate_password_special_char_count | 2 |
-------------------------------------------------------------
7 rows in set (0.00 sec)
mysql create user test33% identified WITH mysql_native_password by2167sags$er24sfwjdtegcfaskvc;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql set global validate_password_mixed_case_count2;
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 | /usr/share/dict/words |
| validate_password_length | 25 |
| validate_password_mixed_case_count | 2 |
| validate_password_number_count | 2 |
| validate_password_policy | STRONG |
| validate_password_special_char_count | 2 |
-------------------------------------------------------------
7 rows in set (0.00 sec)
2. 连接控制插件
MySQL 5.7 版本为连接控制插件功能基本相同以下操作仅以 5.7 版本操作为例。
################## 以5.7版本为例 ##################
## 1. 查看当前连接插件配置信息
mysql show variables like connection_control%;
--------------------------------------------------------
| Variable_name | Value |
--------------------------------------------------------
| connection_control_failed_connections_threshold | 3 |
| connection_control_max_connection_delay | 86400 |
| connection_control_min_connection_delay | 1000 |
--------------------------------------------------------
3 rows in set (0.00 sec)## 2. 新建测试用户后尝试三次连接失败观察等待时间观察到等待反馈登录失败的时间会越来越长
mysql create user test33% identified WITH mysql_native_password by1qazWSX#EDC4rfv5tgb6yhnZVAF;
Query OK, 0 rows affected (0.00 sec)
mysql ^DBye
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user test33localhost (using password: YES)
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user test33localhost (using password: YES)
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user test33localhost (using password: YES)
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user test33localhost (using password: YES)
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user test33localhost (using password: YES)
[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p -S /opt/mysql/data/3306/mysqld.sock
Enter password:
3. 密码变更策略
MySQL 密码变更策略配置记录在 mysql.user 表中5.7 和 8.0 版本支持的配置略有差异以下将展示两个版本的测试过程和测试结果。
################## 以5.7版本为例 ##################
## 1. 检查当前密码变更策略相关信息
mysql select default_password_lifetime\G
*************************** 1. row ***************************
default_password_lifetime: 365
1 row in set (0.00 sec)## 2. 新建 test33 用户设置其密码过期时间为一天修改机器时间重启再使用该用户进行登录操作观察到提示密码过期
mysql CREATE USER test33%- IDENTIFIED WITH mysql_native_password - BY- 1qazWSX#EDC4rfv5tgb6yhnZVAF- REQUIRE NONE - PASSWORD EXPIRE INTERVAL 1 DAY;
Query OK, 0 rows affected (0.00 sec)mysql select user,host,password_lifetime from mysql.user where host!localhost and user not in (mysql.infoschema,mysql.session,mysql.sys);
-------------------------------------------
| user | host | password_lifetime |
-------------------------------------------
| root | 127.0.0.1 | NULL |
| universe_op | % | NULL |
| test4 | % | NULL |
| tt | % | NULL |
| test33 | % | 1 |
-------------------------------------------
5 rows in set (0.00 sec)[root10-186-60-13 dict]# date
Tue Aug 22 16:53:22 CST 2023
[root10-186-60-13 dict]# timedatectl set-time 2023-8-23 16:53:20
[root10-186-60-13 dict]# date
Wed Aug 23 16:53:20 CST 2023[root10-186-60-13 ~]# /opt/mysql/base/5.7.25/bin/mysql -utest33 -p1qazWSX#EDC4rfv5tgb6yhnZVAF -S /opt/mysql/data/3306/mysqld.sock
mysql select now();
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.################## 以8.0版本为例 ##################
##1.检查当前密码变更策略相关信息
mysql select default_password_lifetime,password_history,password_reuse_interval,password_require_current\G
*************************** 1. row ***************************
default_password_lifetime: 365password_history: 5password_reuse_interval: 1password_require_current: 1
1 row in set (0.00 sec)## 2. 进行验证
## 2.1 密码过期验证参考 5.7 此处不再赘述## 2.2 新建 test33 用户并进行密码修改测试当使用近 5 次密码时是否能修改密码成功
mysql create user test33% identified WITH mysql_native_password by1qazWSX#EDC4rfv5tgb6yhnZVAF;
mysql alter user test33% identified WITH mysql_native_password by1qazWSX#EDC4rfv5tgb6yhnZVAF;
ERROR 3638 (HY000): Cannot use these credentials for test33% because they contradict the password history policy
mysql alter user test33% identified WITH mysql_native_password by1qazWSX#EDC4rfv5tgb6yhnZVAG;
Query OK, 0 rows affected (0.00 sec)
mysql alter user test33% identified WITH mysql_native_password by1qazWSX#EDC4rfv5tgb6yhnZVAF;
ERROR 3638 (HY000): Cannot use these credentials for test33% because they contradict the password history policy
知识补充
关于 validate_password.dictionary_file 的配置说明。
validate_password.dictionary_file 参数指定的密码字典文件采用以下逻辑
该文件最大为 1M一行作为一个字符串该文件仅在 validate_password.policy 参数设置为 2 或者 STRONG 时生效 每行至少 4 位长最多 100 位长低于或高于长度均不生效该文件中英文字母必须均为小写但匹配密码时会忽略大小写对文件中每行字符采用模糊匹配也就是密码中不允许出现这串字符串如文件中一行为 zhenxing则适配规则如下
-- 密码字段文件内容
cat /data/mysql/3306/tmp/password_list.txt
zhenxingcreate user demo identified by aaBB11__zhenxing; -- 不支持包含完整的 zhenxing 字符串
create user demo identified by aaBB1zhenxing1__; -- 不支持包含完整的 zhenxing 字符串
create user demo identified by zhenxingaaBB11__; -- 不支持包含完整的 zhenxing 字符串
create user demo identified by aaBB1zhen00xing1__; -- 支持
对该文件新增或删除数据都需要重新配置才可动态生效如先调整为默认值再重新设置为指定文件值。 set global validate_password.dictionary_filedefault;set global validate_password.dictionary_file/data/mysql/3306/tmp/password_list.txt;可以观测 show global status like validate_password.dictionary_file%; 的输出查看文件最新生效时间 该文件主要功能实际类似背景需求中的场景【密码不能包含指定的字符如公司名称、业务名称等】可以将公司名称、业务名称等在该文件中配置
总结
在使用以上功能前需确定不同 MySQL 版本支持度MySQL 5.7 版本上的部分插件到 MySQL 8.0 后调整为了组件使用时需注意语法和参数名称的变化MySQL 8.0 版本对密码进行了更精细化的配置如增加了 password_history、password_reuse_interval 等配置在对 MySQL 配置 default_password_lifetime 时需要注意对业务的影响防止密码过期导致业务中断的风险连接控制插件的使用需要注意避免大量错误异常导致账号连接等待时间拉长具体是否启用也需结合业务场景和安全性综合判断
需求中未实现的功能
密码在 24 小时内最多只能修改一次密码不能是简单的重复字符例如AAAwuwuwuwu, dsadsadsa, 111
更多技术文章请访问https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库为开发和运维提供流程自动化能力提升上线效率提高数据质量。
SQLE 获取
类型地址版本库https://github.com/actiontech/sqle文档https://actiontech.github.io/sqle-docs/发布信息https://github.com/actiontech/sqle/releases数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse