基线核查与加固 - MySQL
基于
MySQL8.0.12
进行操作,环境:phpstudy_pro
&Windows11
- 网络安全等级保护基本要求 -
第三级安全要求
-安全计算环境
- 核查
- 加固
8.1.4 安全计算环境
8.1.4.1 身份鉴别
本项要求包括:
a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换;
- 核查密码复杂度
- 核查密码生命周期
b) 应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施;
- 核查是否限制非法登录次数
- 核查登录连接超时配置
c) 当进行远程管理时,应采取必要措施防止鉴别信息在网络传输过程中被窃听;
- 核查是否开启远程加密通信
d) 应采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别,且其中一种鉴别技术至少应使用密码技术来实现。
- 不适用
核查密码复杂度
MySQL 系统自带有 validate_password 插件,此插件可以验证密码强度,未达到规定强度的密码则不允许被设置。MySQL 5.7 及 8.0 版本默认情况下貌似都不启用该插件,这也使得我们可以随意设置密码,比如设置为 123、123456等。如果我们想从根源上规范密码强度,可以启用该插件,下面一起来看下如何通过此插件来设置密码复杂度策略。
核查方式
安装前检查 为空则说明未安装此插件:show variables like 'validate%';
1 | mysql> show variables like 'validate%'; |
加固方式
1)安装 validate_password 插件
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
1 | # 通过 INSTALL PLUGIN 命令可安装此插件 |
2)密码强度相关参数解释
安装 validate_password 插件后,多了一些密码强度相关参数,这些参数从字面意思上也很容易看懂,下面简单解释下几个重点参数。
1 | 1. validate_password_policy |
3)密码复杂度策略具体设置
set global validate_password_length = 16;
1 | # 设置密码长度至少10位 |
!!! note “若想永久生效,建议将以下参数写入配置文件”
1
2
3
4
5
[mysqld]
plugin-load = validate_password.dll
validate_password_length = 16
validate_password_policy = 1
validate-password = FORCE_PLUS_PERMANENT
核查密码生命周期
核查方式
查看密码有效期:SHOW VARIABLES LIKE 'default_password_lifetime';
default_password_lifetime
设置为0
,即表示密码永不过期。
加固方式
一次性设置全局过期策略:
SET GLOBAL default_password_lifetime = 90;
或者直接写入配置文件并重启以永久生效
1
2
3# 写入配置文件使得重启生效
[mysqld]
default_password_lifetime = 90
设置全局过期策略后,需要把配置写入配置文件
mysql.cn
中并重启才能永久生效,否则MySQL
重启后恢复默认值。
核查是否限制非法登录次数
MySQL>= 5.7.17 以后提供了 Connection-Control 插件,用来控制客户端在登录操作连续失败一定次数后的响应的延迟。
核查方式
show variables like '%connection_control%';
- 为空,则未启用插件,需要安装再进行加固。
加固方式
1)安装 Connection-Control 插件
- CONNECTION_CONTROL:用来控制登录失败的次数及延迟响应时间。
- CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS:该表将登录失败的操作记录至IS库中。
1 | # 每个平台的文件名后缀都不同 对于 Unix 和类 Unix 系统,为.so,对于 Windows 为.dll |
2)参数解释
connection_control_failed_connections_threshold
- 失败尝试的次数,默认为3,表示当连接失败3次后启用连接控制,0表示不开启。
connection_control_max_connection_delay
- 响应延迟的最大时间,默认约25天
connection_control_min_connection_delay
- 响应延迟的最小时间,默认1000微秒,1秒
3)具体配置
方式一:修改配置文件 my.cnf
or my.ini
(永久生效)
1 | # vim /etc/my.cnf |
方式二:设置全局变量(重启失效)
1 | # 登陆失败次数限制 |
核查超时功能
从官方文档上来看 wait_timeout 和 interactive_timeout 都是指不活跃的连接超时时间,连接线程启动的时候wait_timeout会根据是交互模式还是非交互模式被设置为这两个值中的一个。
如果我们运行mysql -uroot -p命令登陆到mysql,wait_timeout就会被设置为interactive_timeout的值。
如果我们在wait_timeout时间内没有进行任何操作,那么再次操作的时候就会提示超时,这时 mysql client会重新连接。
MySQL连接超时退出主要看三个参数:
interactive_timeout
- 服务器关闭交互式连接前等待活动的秒数。
wait_timeout
- 服务器关闭非交互连接之前等待活动的秒数。
两者生效取决于
- 客户端是交互或者非交互的连接。
- 在交互模式下,interactive_timeout才生效;非交互模式下,wait_timeout生效。
connect_timeout =10
- 指的是连接过程中握手的超时时间(s)
核查方式
show global variables like '%timeout%';
加固方式
1 | # 设置全局变量 `connect_timeout` 为 `10s` |
核查是否开启远程加密通信
核查方式
show variables like 'have_openssl';
SHOW VARIABLES LIKE '%ssl%';
MySQL8.0.12默认开启加密通信
禁用加密通信:在配置文件
my.cnf
中的[mysqld]
下加入skip_ssl
,重启MySQL。
加固方式
加固通信传输要求项:启用 ssl
加密通信,注释 配置文件 my.cnf
中的 [mysqld]
下的skip_ssl
,并在下面追加 ssl
,重启MySQL。
8.1.4.2 访问控制
本项要求包括:
a) 应对登录的用户分配账户和权限;
- 核查是否对登录的用户分配账户和权限
b) 应重命名或删除默认账户,修改默认账户的默认口令;
- 核查是否重命名账号
- 核查是否修改默认口令
c) 应及时删除或停用多余的、过期的账户,避免共享账户的存在;
- 核查是否存在多余的、过期的账号
d) 应授予管理用户所需的最小权限,实现管理用户的权限分离;
e) 应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;
f) 访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;
g) 应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
核查是否对登录的用户分配账户和权限
核查方式
1 | # MySQL 中所有使用者的权限是记录在 `mysql` 这个数据库的 `user` 资料表中: |
加固方式
禁止root账号远程登录
禁止程序使用root账号
1
2
3
4-- 设置允许任何IP登录
use mysql;
update user set host='localhost' where user='root' and host='%';
flush privileges;
核查是否重命名账号
核查方式
SELECT user, host FROM mysql.user
加固方式
修改root账号名
1
2
3use mysql;
update user set user='haiyi_root' where user='root' and host='localhost';
flush privileges;
核查是否修改默认口令
核查方式
- 访谈
- 查询空口令账号
select * from mysql.user where length(authentication_string)=0 or authentication_string is null;
加固方式
- 修改默认口令、空口令(谨慎操作)
1 | mysql> USE mysql; |
核查是否存在多余的、过期的账号
核查方式
SELECT user, host FROM mysql.user
加固方式
删除多余的、过期的账号,如:test, dev等测试账号。
删除
test
:drop user 'test'@'localhost';
删除
dev
:drop user 'dev'@'localhost';
8.1.4.3 安全审计
本项要求包括:
a) 应启用安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计;
- 核查是否启用日志记录
b) 审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息;
c) 应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等;
- 核查日志保存时间
- 核查日志文件权限信息
d) 应对审计进程进行保护,防止未经授权的中断。
核查是否启用日志记录
核查方式
- 查询所有日志相关信息:
show variables like '%log%';
加固方式
1) 开启常规日志审计功能
set global general_log=on;
2) 开启错误日志审计功能
1 | # 错误日志包括数据库运行和停止过程中的一系列活动信息,有助于分析数据库运行过程中的一些异常活动 |
3) 确保日志存放在非系统区域
1 | # 日志文件随着数据库的运行会不断增加,如果存放在系统区域,则会影响系统的正常运行,使用如下命令进行查询: |
4) 关闭原始日志功能
当
log-raw
记录启用时,有权访问日志文件的人可能会看到纯文本密码。编辑 MySQL 配置文件
/etc/my.cnf
,删除log-raw
参数,并重启mysql
服务上述与下面的操作好像有点冲突,以实际情况为准。待探索……
1 | # 原始日志选项会决定一些敏感信息是否会被明文写进日志中,例如查询日志、慢查询日志、二进制日志 |
核查日志保存时间
set global expire_logs_days=365
> 3683 - The option expire_logs_days and binlog_expire_logs_seconds cannot be used together. Please use binlog_expire_logs_seconds to set the expire time (expire_logs_days is deprecated)
核查方式
- 查看日志时间(已废弃):
show variables like '%logs_days%';
- 查看日志时间:
show variables like 'binlog_expire_logs_seconds';
加固方式
set global binlog_expire_logs_seconds=2596096;
核查日志文件权限信息
1) 控制二进制日志文件的权限
1 | # mysql的运行会产生很多日志,例如二进制日志、错误日志、慢查询日志等等,Mysql命令行下执行如下命令: |
2) 控制数据目录、基准目录的访问权限
1 | # 数据目录是mysql数据库存放的位置,在mysql命令行界面下执行如下命令: |
3) 控制错误日志文件的权限
1 | # 控制错误日志文件的权限 |
4) 控制慢查询日志文件的权限
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录MySQL中查询时间超过(大于)设置阈值(long_query_time)的语句,记录到慢查询日志中。
默认情况下,MySQL没有开启慢查询日志。需要手动打开,如果不是调优需要的话,不建议开启,因为开启会带来一定的性能影响,慢查询日志支持将日志记录写入文件。
1 | # 开启慢查询日志,只对当前数据库生效,并且重启数据库后失效 |
慢查询日志文件权限控制查看与设置:
1 | # Mysql命令行下执行如下命令: |
5) 控制通用日志文件的权限
1 | # Mysql命令行下执行如下命令: |
6) 控制审计日志文件的权限
Naming Conventions for Audit Log Files
To configure the audit log file name, set the
audit_log_file
system variable at server startup. The default name isaudit.log
in the server data directory. For best security, write the audit log to a directory accessible only to the MySQL server and to users with a legitimate reason to view the log.[MySQL :: MySQL 8.0 Reference Manual :: 6.4.5.5 Configuring Audit Logging Characteristics](https://dev.mysql.com/doc/refman/8.0/en/audit-log-logging-configuration.html#:~:text=To configure the audit log file name%2C set,with a legitimate reason to view the log.)
1 | # Mysql命令行下执行如下命令: |
8.1.4.4 入侵防范
本项要求包括:
a) 应遵循最小安装的原则,仅安装需要的组件和应用程序;
- 核查测试数据库以及空账号
b) 应关闭不需要的系统服务、默认共享和高危端口;
c) 应通过设定终端接入方式或网络地址范围对通过网络进行管理的管理终端进行限制;
- 核查是否限制源IP访问
d) 应提供数据有效性检验功能,保证通过人机接口输入或通过通信接口输入的内容符合系统设定要求;
e) 应能发现可能存在的已知漏洞,并在经过充分测试评估后,及时修补漏洞;
核查是否及时打补丁
f) 应能够检测到对重要节点进行入侵的行为,并在发生严重入侵事件时提供报警。
核查测试数据库以及空账号
核查方式
- 查询数据库:
show DATABASES;
- 使用该命令查询是否存在空账号:
SELECT user,host FROM mysql.user WHERE user = '';
加固方式
删除测试数据库以及空账号
1 | # 删除冗余数据库, 如 test |
核查是否限制源IP访问
默认需要所有账号进行限制,不能存在 “
%
“ 任意源IP
设置。
核查方式
SELECT user, host FROM mysql.user
加固方式
设置
${账号}
指定源IP登录1
2
3
4
5# update user set host='${IP}' where user='root' and host='%';
# 设置 root 用户只允许本地登录
use mysql;
update user set host='localhost' where user='root' and host='%';
flush privileges;
参考资料
安全标准
产品文档
博客文章
- (100条消息) MySQL数据库安全加固方法_Lee_Natuo的博客-CSDN博客
- MySQL8.0正确修改密码的姿势- 腾讯云开发者社区-腾讯云 (tencent.com)
- (100条消息) mysql8.0.15用户root登录开启远程访问权限_藤叶香来的博客-CSDN博客
- (100条消息) MySQL 8.0 版本授权 root 远程连接,修改权限,更改加密方式_肖朋伟的博客-CSDN博客_mysql8.0更改root 权限
- [(100条消息) Linux系统中,Mysql 8的安装、修改root密码及允许root远程登录_时栈的博客-CSDN博客_mysql8允许root远程连接](https://blog.csdn.net/qq_44667259/article/details/123228144#:~:text=一、CentOS系统中Mysql 8的安装 1 1.安装 sudo yum install mysql-,user from user where user%3D’root’%3B %2F%2F 查看 )
- (100条消息) mysql8.0 删除用户_MYSQL8 创建、删除用户和授权、消权操作_番茄君小弟的博客-CSDN博客
- (100条消息) mysql8.0数据库添加用户和授权_liuzh2443的博客-CSDN博客_mysql8用户授权
- (100条消息) mysql8.0 新增用户_MySQL8.0添加创建用户、删除用户与授权(create user,delete user)_故事档案局的博客-CSDN博客
- (100条消息) mysql connect 超时_MySQL修改connect_timeout(连接超时)全局变量_半清斋的博客-CSDN博客
- MySQL修改connect_timeout(连接超时)全局变量 - 简书 (jianshu.com)
- [(100条消息) mysql 5.7 连接超时参数设置_大龄奋斗程序猿的博客-CSDN博客_mysql 5.7配置超时](https://blog.csdn.net/aichogn/article/details/118113114#:~:text=connect_timeout指的是连接过程中握手的超时时间%2C在 5.0.52 以后默认为,10 秒,之前版本默认是 5 秒。)
- (100条消息) MySQL学习之三级等保整改_Charles Yan的博客-CSDN博客_mysql 等保
- 设置Mysql的连接超时参数wait_timeout、interactive_timeout - 腾讯云开发者社区-腾讯云 (tencent.com)
- (100条消息) Linux MySQL5.7等保问题整改:数据库未配置登录失败处理功能,未配置非法登录策略和登录超时自动退出功能。_可爱的小张666的博客-CSDN博客_mysql超时自动退出功能。
- (100条消息) mysql多次登录失败控制,Mysql登录失败多次锁定配置_Luna Li的博客-CSDN博客
- mysql密码策略和登录失败处理 - windysai - 博客园 (cnblogs.com)
- (100条消息) mysql 修改登录失败处理功能参数_等保测评2.0:MySQL身份鉴别_weixin_39762666的博客-CSDN博客
- MySQL密码复杂度与密码过期策略介绍 - MySQL技术 - 博客园 (cnblogs.com)
- mysql查看密码自动过期时间 - 简书 (jianshu.com)
- (100条消息) MySQL关闭SSL的方法_andyguan01_2的博客-CSDN博客_mysql关闭openssl
- 配置MySQL支持ssl - 简书 (jianshu.com)
- (100条消息) MySQL配置SSL加密连接_guan-qing的博客-CSDN博客_navicate ssl连接
- (100条消息) MySQL数据库安全基线(加固方法)_Lee_Natuo的博客-CSDN博客
- (106条消息) mysql永久修改变量_MySQL 8.0 新特性之持久化全局变量的修改_实在知道什么的博客-CSDN博客
持久化全局变量
全局变量的持久化命令
1) SET PERSIST
- 修改内存值,将全局变量的修改持久化到配置文件中
- 只需要
SYSTEM_VARIABLES_ADMIN
2)SET PERSIST_ONLY
- 只持久化全局变量,而不修改其内存值
- 需要
SYSTEM_VARIABLES_ADMIN
和PERSIST_RO_VARIABLES_ADMIN
权限
3)set persist max_connections=default;
将全局变量持久化为默认值。注意,是默认值,而不是修改前的值。
这个命令同
set global max_connections=default
类似,都会将变量的值设置为默认值,只不过前者还会将默认值持久化到配置文件中。
清除持久化变量命令
1)RESET PERSIST
- 注意,其只是清空
mysqld-auto.cnf
和performance_schema.persisted_variables
中的内容,对于已经修改了的变量的值,不会产生任何影响。
执行脚本
1 | # 核查是否开启加密通信 |