MySQL学习之三级等保整改
前言
-
MySQL基本操作
-- 创建用户 create user 'admin'@'%' identified by '***'; -- 更改密码 alter user 'dev_xl'@'%' IDENTIFIED with mysql_native_password by '****'; -- 重命名 rename user 'admin_xl'@'192.168.200.16' to 'admin_xl'@'%'; -- 刷新权限 FLUSH PRIVILEGES; -- 赋予权限 grant all privileges on *.* to 'admin_xl'@'%'; -- 收回权限 revoke all privileges on *.* from 'admin_xl'@'%'; -- 查看当前登录的用户 select current_user() -- 查看当前登录的用户角色 select current_role()
一、身份鉴别
1.1 登录信息设置
-
基本内容
建议身份密码登录,身份标识具有唯一性,身份鉴别信息具有复杂度要求,密码长度最少为8位,密码由数字、字母大小写、特殊符号组成、并设置定期更换,更换时间最长位90天。
-
整改过程
-
用户身份鉴别的理解:
mysql 数据库对于用户的标识和其他数据库有些不一样的,不仅仅是用户名,而是username+host组合。例如下面的两个root,host不同,其实是两个不同的用户。通过mysql.user表查看是否有重复用户,建议把root用户删掉或重命名。
-
判断空指令:用户user、host、authentication_string 字段全部为空或% 。
-
密码复杂度插件:
查看mysql的插件,发现mysql8.0 并没有校验插件,然后查看插件包,发现有这个插件,则对该插件进行安装。
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
打开/etc/my.cnf 在mysqld 后面添加下面内容重启
plugin-load=validate_password.so validate_password_policy=1 validate-password=FORCE_PLUS_PERMANENT
-
密码复杂度讲解:
在安装完插件后,查看参数。
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.09 sec)
参数介绍
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最小是0 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
-
定期更密码:
在/etc/my.cnf 的文件中将密码有效期时间改为90天。
mysql> show global variables like 'default_password_lifetime'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | default_password_lifetime | 90 | +---------------------------+-------+ 1 row in set (0.01 sec)
查看user表的几个关键字段:它们的单位都是天,当password_lifetime 为null时,则代表该用户当前口令的有效期是使用的全局变量,而default_password_lifetime 为0代表有效期永远。
也就是说,这些项都能符合,唯一需要做的事情就是定期更改密码。
mysql> select user,host,password_lifetime,password_last_changed from mysql.user; +-----------+------+-------------------+-----------------------+ | user | host | password_lifetime | password_last_changed | +-----------+------+-------------------+-----------------------+ | admin_fqr | % | NULL | 2021-03-01 13:58:58 | | admin_xl | % | NULL | 2021-03-01 13:57:48 | | dev | % | NULL | 2021-02-01 17:24:28 | | dev_db | % | NULL | 2021-03-01 10:58:23 | | dev_xl | % | NULL | 2021-03-01 14:01:56 | | log_db | % | NULL | 2021-03-01 10:58:23 | | log_xl | % | NULL | 2021-03-01 14:01:28 | | system_db | % | NULL | 2021-03-01 10:58:23 | +-----------+------+-------------------+-----------------------+ 8 rows in set (0.00 sec)
-
1.2 登录失败处理
-
基本内容
建议数据库配置登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施,可采取登录失败五次锁定三十分钟;登陆超时设置为30分钟自动退出。
-
整改过程
-
mysql 的max_connect_error的理解:
经过调查,发现这个最大连接错误与真正的输入密码错误是不一样的概念。
因此,把这个参数改为 5 是没有意义的,这个参数本质原因是同一个IP在短时间内产生太多中断的数据库连接,超过这个值才不让登录。
mysql> show variables like "%max_connect_error%"; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | max_connect_errors | 100 | +--------------------+-------+ 1 row in set (0.00 sec)
-
mysql的插件安装
因此,这块需要采用CONNECTION_CONTROL(会话控制限制登录次数)和CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS 共同实现。
mysql> Install plugin connection_control soname "connection_control.so"; Query OK, 0 rows affected (0.05 sec) mysql> INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so'; Query OK, 0 rows affected (0.00 sec)
查看两个插件的激活状态:
mysql> select plugin_name,plugin_status from INFORMATION_SCHEMA.PLUGINS where PLUGIN_NAME LIKE 'connection%'; +------------------------------------------+---------------+ | plugin_name | plugin_status | +------------------------------------------+---------------+ | CONNECTION_CONTROL | ACTIVE | | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | ACTIVE | +------------------------------------------+---------------+
-
mysql的参数解读(毫秒):
mysql> show variables like "%connection_control%"; +-------------------------------------------------+---------+ | Variable_name | Value | +-------------------------------------------------+---------+ | connection_control_failed_connections_threshold | 5 | | connection_control_max_connection_delay | 1800000 | | connection_control_min_connection_delay | 1800000 | +-------------------------------------------------+---------+ 3 rows in set (0.01 sec)
connection_control_failed_connections_threshold:在服务器增加后续连接尝试的延迟之前,允许客户端进行的连续失败连接尝试的次数。
connection_control_min_connection_delay:对于超出阈值的每个连续连接失败,要添加的延迟量。
connection_control_max_connection_delay:要添加的最大延迟。
当然,最好是要去my.cnf的文件中添加参数,这是改动后的参数。
connection_control_failed_connections_threshold=5 connection_control_min_connection_delay=1800000 connection_control_max_connection_delay=1800000
-
超时功能:
Mysql 连接超时退出主要看三个参数:
wait_timeout :这个参数的单位是秒,默认是28880
interactive_timeout :交互式登录超时
connect_timeout =10
mysql在使用交互式操作的时候,就是你打开mysql黑窗口进行的操作时使用的是wait_timeout,默认已经配置好了。 在使用非交互式操作时候,就是interactive_timeout,例如你程序的jdbc连接数据库。
-
1.3 远程登录管理
-
基本内容
建议远程管理数据库时建议使用堡垒机+ssh防止鉴别信息在网络传输过程中被窃听;
-
整改过程
- 关于ssh:查看是否开启ssl
mysql> show variables like "%have_ssl%"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_ssl | YES | +---------------+-------+ 1 row in set (0.00 sec)
1.4 其他
-
整改建议
建议数据库采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别,且其中一种鉴别技术至少应使用密码技术来实现。
建议使用ssh+堡垒机来实现。
二、访问控制
2.1 用户权限控制
-
主要内容
-
建议登录用户由管理员分配账户和权限(也就是必须要分成几个角色)。
-
建议重命名或者删除默认账户,修改默认账户的默认口令,或禁用默认账户(简单略过)。
-
建议删除或停用多余的、过期的账户,避免共享账户的存在;根据需要创建每个人员对应的账户。
-
建议建立、操作员、审计员、安全管理员等角色,安全管理为制定安全策略人员、操作员为日常操作用户、审计员只需具有审计日志查看权限;实现用户所需权限最小化,和管理用户权限分离。
-
-
整改过程
-
首先创建三个角色:操作员、审计员、管理员。
操作员:负责业务层面开发,对应我们开发人员。
审计员:只需对日志具有审查权限
管理员:拥有所有的权限,制定安全策略。
mysql> create role 'system_db','dev_db','log_db'; Query OK, 0 rows affected (0.02 sec)
-
创建用户,给管理员角色分配所有权限
禁止将file,process ,super 权限分给管理员之外的人员。
mysql> GRANT ALL privileges on *.* to 'system_db'@'%' with grant option; Query OK, 0 rows affected (0.01 sec) mysql> create user 'admin'@'%' identified by 'giantAdmin@2021'; Query OK, 0 rows affected (0.01 sec) mysql> grant 'system_db' to 'admin'@'%'; Query OK, 0 rows affected (0.00 sec)
- 查看该角色的权限
mysql> show grants for 'admin'@'%'; +--------------------------------------+ | Grants for admin@% | +--------------------------------------+ | GRANT USAGE ON *.* TO `admin`@`%` | | GRANT `system_db`@`%` TO `admin`@`%` | +--------------------------------------+ 2 rows in set (0.00 sec)
【注释】:USAGE 是连接(登陆)权限,建立一个用户,就会自动授予其usage权限(默认授予)。该权限不能被回收,不管它。
-
创建用户,给开发角色分配权限。
对于开发人员:
1)赋予用户对数据库的增删改操作;
2)赋予用户创建,修改,删除表结构;操作mysql外键权限、操作临时表权限、操作索引权限、操作mysql视图、操作mysql存储过程权限;
3)赋予用户全局权限:reload,process。查看所有进程
mysql> create user 'dev_xl'@'%' identified by 'giantDev@xl2021'; Query OK, 0 rows affected (0.02 sec) mysql> grant 'dev_db' to 'dev_xl'@'%'; Query OK, 0 rows affected (0.01 sec) ============ 下面是具体针对某个库所加的权限 ============= ===1、针对wiedp库的权限==== mysql> grant select,insert,update,delete on wiedp.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> grant create,drop,alter,references,create view ,show view ,create routine,alter routine,create temporary tables,index,execute on wiedp.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> grant reload,process on *.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.00 sec) === 2、针对wiedp_sub 的权限=== mysql> grant select,insert,update,delete on wiedp_sub.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> grant create,drop,alter,references,create view ,show view ,create routine,alter routine,create temporary tables,index,execute on wiedp_sub.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.01 sec) === 3、针对official的权限 ==== mysql> grant select,insert,update,delete on official.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> grant create,drop,alter,references,create view ,show view ,create routine,alter routine,create temporary tables,index,execute on official.* to 'dev_db'@'%'; Query OK, 0 rows affected (0.00 sec)
-
创建审计员,分配角色
1) 分配审计人员对auditlog库的查询和插入删除权限。
mysql> create user 'log_xl'@'%' identified by 'giantLog@xl2021'; Query OK, 0 rows affected (0.02 sec) mysql> grant 'log_db' to 'log_xl'@'%'; Query OK, 0 rows affected (0.01 sec) === 赋权=== mysql> grant insert,select,delete on auditlog.t_audit to 'log_db'; Query OK, 0 rows affected (0.00 sec) mysql> grant reload,process on *.* to 'log_db'@'%'; Query OK, 0 rows affected (0.00 sec)
-
激活角色
需要注意的是,角色创建后,并不会直接激活,激活的方式有几种,但推荐的一种就是去配置文件配置参数。
当用户登录后,可以查看该角色是否存在。查看参数是off状态。更改位on,该角色在登录后就会被自动激活。
mysql> select current_role(); +----------------+ | current_role() | +----------------+ | NONE | +----------------+ mysql> show global variables like 'activate_all_roles_on_login'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | activate_all_roles_on_login | OFF | +-----------------------------+-------+ 1 row in set (0.00 sec)
-
三、安全审计
3.1 配置审计功能
-
基本内容
建议数据库开启安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计;
-
整改过程
- 查看审计配置情况
mysql> show global variables like 'log_timestamps'; +----------------+-------+ | Variable_name | Value | +----------------+-------+ | log_timestamps | UTC | +----------------+-------+ 1 row in set (0.01 sec) mysql> show global variables like '%general%'; +------------------+-----------------------------------------+ | Variable_name | Value | +------------------+-----------------------------------------+ | general_log | OFF | | general_log_file | /opt/software/mysql8/data/localhost.log | +------------------+-----------------------------------------+ 2 rows in set (0.01 sec)
【解析】:初始的参数如上,其中含义如下:
log_timestamps表示记录审计日志的时间是从哪里获取。UTC是全球时间,改成system系统当前时间
general_log表示审计功能是否开启,
general_log_file表示审计信息的存储文件
-
开启审计功能
在/etc/my.cnf 文件中添加内容,然后重启mysql
general_log=on general_log_file=/home/mysql8/data/auditlog.log log_timestamps=system
- 重启后,重新查看配置
mysql> show global variables like 'log_timestamps'; +----------------+--------+ | Variable_name | Value | +----------------+--------+ | log_timestamps | SYSTEM | +----------------+--------+ 1 row in set (0.00 sec) mysql> show global variables like '%general%'; +------------------+----------------------------------------+ | Variable_name | Value | +------------------+----------------------------------------+ | general_log | ON | | general_log_file | /opt/software/mysql8/data/auditlog.log | +------------------+----------------------------------------+ 2 rows in set (0.00 sec)
- 测试审计功能
对表进行操作后查看这个auditlog文件,存在记录
ORDINAL_POSITION, SUBPARTITION_ORDINAL_POSITION 2021-03-01T11:55:09.393973+08:00 9 Init DB test 2021-03-01T11:55:09.400381+08:00 9 Query SELECT * FROM `test`.`user_test` LIMIT 0,1000 2021-03-01T11:55:09.421726+08:00 10 Connect dev@192.168.200.16 on using TCP/IP 2021-03-01T11:55:09.425147+08:00 10 Query SET NAMES utf8mb4 2021-03-01T11:55:09.432346+08:00 10 Init DB test 2021-03-01T11:55:09.436096+08:00 10 Init DB test
-
设置init-connect
到此为止,已经设置好审计功能了,但是这是记录了所有对数据库的操作,所以接下来我们将通过init-connect + binlog来实现相对完整的审计功能。
(a) 创建用于存放连接日志的数据库和表
mysql> create database auditlog; Query OK, 1 row affected (0.01 sec) mysql> create table auditlog.t_audit( -> id int not null auto_increment, -> thread_id int not null, -> login_time timestamp, -> localname varchar(50) default null, -> matchname varchar(50) default null, -> primary key (id) -> )ENGINE=InnoDB default charset=utf8 comment '审计用户登录信息'; Query OK, 0 rows affected, 1 warning (0.03 sec)
(b) 授权所不同角色对审计表的操作权限
mysql> grant insert on auditlog.t_audit to 'dev_db'; Query OK, 0 rows affected (0.01 sec) mysql> grant insert,select,delete on auditlog.t_audit to 'log_db'; Query OK, 0 rows affected (0.00 sec)
-
设置init-connect参数
在/etc/my.cnf 中配置如下信息,完成日志审计
init-connect='insert into auditlog.t_audit(id,thread_id,login_time,localname,matchname) values(null,connection_id(),now(),user(),current_user());'
-
测试结果如下:
【解析】:为什么开启了审计功能后,还需要做一个记录用户登录信息的表呢?
1、无论sql有无语法错误,只要执行了就会记录,导致记录大量无用信息,后期的筛选有难度。因此加了表后可以根据一个大体的操作时间来进行筛选出这个时间段中执行这个操作的登陆用户的thread_id,然后再在表中查找这个thread_id号是哪个用户登陆的就可以很快筛选出执行具体某个操作的用户了。
2、因为新建的表普通用户没有权限删除记录,而log文件时可以删除记录的,所以若没有审计表的话若普通用户能接触保存log的那台主机,则能手动删除。
3.2 审计内容设置
-
基本内容
审计记录应包括事件的日期、用户、事件类型、事件是否成功及其他与审计相关的信息。
-
整改过程
只要启用了审计功能,无论是自带的审计还是插件,在记录的信息上都能满足这个要求。
3.3 审计记录备份
-
基本内容
应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖
-
整改过程
-
如果审计记录存储在文件中,那么在操作系统上需要对这些日志文件的权限进行限定,仅允许数据库管理员可对文件进行访问、修改等。同时也要限制MYSQL中的file_priv权限。
-
如果审核记录存储在数据库表中,那么也应该对数据库的表进行权限设置,仅数据库管理员可对审核记录进行访问、修改等。
-
3.4 审计进程保护
-
基本内容
应对审计进程进行保护,防止未经授权的中断
-
整改过程
需要对审计过程进行配置,一个是my.cnf ,这里就需要操作系统对配置文件的权限进行限制,只允许数据库管理有权限进行修改。(同时也要限制mysql的file_priv 权限)。
另外一个就说那些变量了,似乎是需要super权限才可以设置全局变量,那么就需要查看super权限给了哪些账户。
四、入侵防范
4.1 设定远程登录限制
-
基本内容
建议设定终端接入方式或设置网络地址范围,只允许特定IP或地址段进行登录。只允许公司内网通过ssh远程登录。
-
整改过程
应该查看用户登录的地址是否给所有用户加上了IP限制。 如果在防火墙上限定了特定的终端IP进行访问这个数据库,那么是符合要求的。
需要把之前的 host网段设为某个制定的IP网段。注意,用户表和角色表的to_host要一致
五、可信验证
新增可信技术验证(建议)
-
基本内容
将来可考虑采用可信技术基于可信根对边界设备的系统引导程序、系统程序、重要配置参数和边界防护应用程序等进行可信验证,并在应用程序的关键执行环节进行动态可信验证,在检测到其可信性受到破坏后进行报警,并将验证结果形成审计记录送至安全管理中心。
成本太高不建议整改
六、数据完整性和保密性
6.1 数据完整性措施
-
数据传输整改
建议采用堡垒机+ssh技术保证重要数据在传输过程中的完整性和保密性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等;
-
数据存储整改
建议采用MD5或者其他相同功能的技术保证重要数据在存储过程中的完整性和保密性,包括但不限于鉴别数据、重要业务数据、重要审计数据、重要配置数据、重要视频数据和重要个人信息等。建议对个人信息加密储存,实现部分整改。
也就是说敏感信息,例如用户密码、手机号等需要进行加密存储。
七、数据备份恢复
7.1 备份措施
-
主要内容
-
建议提供重要数据的本地数据备份与恢复功能;
-
建议提供异地实时备份功能,利用通信网络将重要数据实时备份至备份场地;实现异地灾备。建议在阿里云其他区域进行异地备份
-
建议数据库使用热冗余或者使用高可用版数据库,保证系统的高可用性。
-
参考链接
-
mysql运维手册
http://www.sunrisenan.com/docs/mysql/15mysql.html
-
【MySQL基础】4- MySQL配置文件 my.cnf
https://www.codeleading.com/article/98105879978/
-
MySQL之interactive_timeout和wait_timeout
https://cloud.baidu.com/doc/RDS/s/yk2yf10q2
-
MySQL 角色(role)功能介绍
https://www.jb51.net/article/210464.htm
-
你真的熟悉MySQL权限吗?
https://cloud.tencent.com/developer/article/1056271
-
MySQL 角色
https://www.begtut.com/mysql/mysql-roles.html#
-
你的MySQL服务器开启SSL了吗?
https://www.cnblogs.com/mysql-dba/p/7061300.html