MySQL安全加固
【实验目的】
通过本实验掌握并实现MySQL基础加固。
【知识点】
1. validate_password插件
(1)validate_password插件是mysql5.6以后可以引入的一个新密码校验插件,可通过配置对用户密码长度、强度进行管理。validate_password文件名后缀根据平台的不同而不同(例如:.so对于Unix和类Unix系统,.dll对于Windows)。
密码策略可以通过以下命令查询(均可)。
SHOW VARIABLES LIKE 'validate_password%';
SELECT @@validate_password_policy;
(2)各字段描述参考下表属性信息与密码强度等级。
- 属性信息
属性 | 默认值 | 属性描述 |
---|---|---|
validate_password_check_user_name | OFF | 设置为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 | right-aligned 密码强度检验等级,可以使用数值0、1、2或相应的符号值LOW、MEDIUM、STRONG来指定。0/LOW:只检查长度。1/MEDIUM:检查长度、数字、大小写、特殊字符。2/STRONG:检查长度、数字、大小写、特殊字符、字典文件。 |
validate_password_special_char_count | 1 | 密码必须包含的特殊字符个数 |
- 密码强度等级
密码规则 | 强度得分 |
---|---|
Length < 4 | 0 |
Length ≥ 4 and < validate_password_length | 25 |
Satisfies policy 1 (LOW:只验证长度) | 50 |
Satisfies policy 2 (MEDIUM:验证长度、数字、大小写、特殊字符) | 75 |
Satisfies policy 3 (STRONG:验证长度、数字、大小写、特殊字符、字典文件) | 100 |
若想要自定义设置密码策略,可以通过set global 字段名=自定义值
设置validate_password_policy属性或其它属性来实现。
2. MySQL用户权限
- 数据库授权,一般用户权限有以下几种:
alter: 修改已存在的数据表(例如增加/删除列)和索引
create: 建立新的数据库或数据表
delete: 删除表的记录
drop: 删除数据表或数据库
index: 建立或删除索引
insert: 增加表的记录
select: 显示/搜索表的记录
update: 修改表中已存在的记录 - 特别的权限
ALL: 允许做任何事(和root一样)
USAGE: 只允许登录–其它什么也不允许做
3. MySQL授权命令
(1)授权命令格式:
grant privileges ON database.table TO 'username'[@'host'] [with grant option]
privileges (权限列表),可以是 all ,表示所有权限,也可以是 select、update 等权限,多个权限之间用逗号分开。
ON 用来指定权限针对哪些库和表,格式为 数据库.表名 ,点号前面用来指定数据库名,点号后面用来指定表名, . 表示所有数据库所有表。
TO 表示将权限赋予某个用户, 格式为 username@host ,@前面为用户名,@后面接限制的主机,可以是IP、IP段、域名以及%,%表示任何地方。
WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。
(2)撤销用户权限:
revoke privileges ON database.table FORM '用户名'[@'主机'];
(3)授权原则说明:
只授予能满足需要的最小权限,比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。
创建用户的时候限制用户的登录主机,一般是限制成指定IP或者内网IP段。
初始化数据库的时候删除没有密码的用户,安装完数据库的时候会自动创建一些用户,这些用户默认没有密码。
为每个用户设置满足密码复杂度的密码。
定期清理不需要的用户,回收权限或者删除用户。
4. Windows普通用户运行MySQL服务
在Windows系统中,若不进行特殊配置则服务默认以System最高权限运行,这在实际生产环境中是不允许的。需要创建普通用户,并通过服务修改运行用户,以普通用户进行运行。
5. 数据库备份
mysqldump 是 MySQL 自带的逻辑备份工具。它的备份原理是通过协议连接到 MySQL 数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的insert 语句,当需要还原这些数据时,只要执行这些 insert 语句,即可将对应的数据还原。
(1)命令格式为:
mysqldump [选项] 数据库名 [表名] > 脚本名
--host | -h | 服务器IP地址 |
---|---|---|
--port | -P | 服务器端口号 |
--user | -u | MySQL用户名 |
--password | -p | MySQL密码 |
--databases | 指定要备份的数据库 | |
--all-databases | 备份mysql服务器上的所有数据库 |
【实验原理】
分别从账号、口令安全、访问控制、安全审计、数据备份、补丁等角度对MySql数据库进行加固。
【软件工具】
- 服务器:Windows server 2016一台;
- 数据库:MySQL 5.7.34。
【实验目标】
- 通过命令查找匿名账户并删除。
- 通过密码插件,加固口令。
- 通过审计插件记录数据库操作。
【实验步骤】
1. 登录mysql服务。
(1)登录实验拓扑中的Window2016设备,登录用户名/密码为Administrator/com.1234。
(2)调用cmd,输入如下命令,回车键登录mysql,密码为123456。如图所示。
mysql -uroot -p
2. 口令加固
(1)validate_password 是 mysql5.6以后可以引入的一个新密码校验插件, 管理用户密码长度、强度等。validate_password文件名后缀根据平台的不同而不同(例如,.so对于Unix和类Unix系统,.dll对于Windows)。
(2)安装插件:输入如下命令查看插件,通过查看当前插件信息,了解到当前环境并没有开启插件。如图所示。
show plugins;
(3)执行如下命令,安装插件。如图所示。
install plugin validate_password soname 'validate_password.dll';
(4)执行如下命令,查看当前密码规则强度。如图所示。
SELECT @@validate_password_policy;
(5)查看密码策略的具体信息。如图所示。
SHOW VARIABLES LIKE 'validate_password%';
validate_password_number_count :密码中至少含有的数字个数,当密码策略是MEDIUM或以上时生效。
validate_password_special_char_count :密码中非英文数字等特殊字符的个数,当密码策略是MEDIUM或以上时生效。
validate_password_mixed_case_count :密码中英文字符大小写的个数,当密码策略是MEDIUM或以上时生效。
validate_password_length :密码的长度
validate_password_dictionary_file :指定密码验证的字典文件路径。
validate_password_policy :这个参数可以设为0、1、2,分别代表从低到高的密码强度,此参数的默认值为1,如果想将密码强度改弱,则更改此参数为0。
所以,不仅可以通过设置validate_password_policy属性来修改密码强度,还可以通过修改其它属性。只是通过validate_password_policy比较方便。
(6)当开启默认口令策略后,此时若新创建一个弱口令用户,会进行错误提醒。如图所示。
CREATE USER "test1"@"localhost" IDENTIFIED BY "123456";
3. 账户配置
(1)检查匿名账户:如果在安装MySQL的时候没有特殊措施,那么mysql会默认含有匿名用户,如下结果:输入exit退出root用户登录,直接执行mysql ,不指定用户信息便能够登录。如图所示,登录成功说明存在匿名账户。
(2)执行exit退出匿名账户登录,切换root账户,执行如下命令,查看匿名账户。如图所示。
SELECT user,authentication_string FROM mysql.user;
(3)执行如下命令删除匿名账户。如图所示。
DELETE FROM mysql.user WHERE user="";
(4)删除无关账户:如果与业务和数据库无关的账号应删除。
(5)修改默认root管理用户。如图所示。
use mysql;(切换到mysql数据库)
UPDATE user SET user="newroot" WHERE user="root";(更新root用户的用户名为newroot)
FLUSH PRIVILEGES;(刷新权限,将使更新后的用户名生效)
4. 权限与访问控制
- 数据库授权,一般用户权限有以下几种:
alter: 修改已存在的数据表(例如增加/删除列)和索引
create: 建立新的数据库或数据表
delete: 删除表的记录
drop: 删除数据表或数据库
index: 建立或删除索引
insert: 增加表的记录
select: 显示/搜索表的记录
update: 修改表中已存在的记录- 特别的权限
ALL: 允许做任何事(和root一样)
USAGE: 只允许登录–其它什么也不允许做
(1)查看用户权限:通过命令可以看出,tt用户仅有登录权限。如图所示。
SELECT user,host FROM user;
SHOW GRANTS FOR tt@"localhost";(用来显示指定用户在特定主机上的权限信息。其中,"tt" 是用户名,"localhost" 是主机名。该命令会显示用户 "tt" 在 "localhost" 上的授权情况,包括其具有的权限以及可以操作的数据库和表等信息。)
(2)通过 tt用户登录mysql,密码为123456,可以看到仅有一个系统库,但并不能进行任何操作。如图所示。
(3)切换到root用户,通过命令赋予tt用户其它权限。如图所示。
注:此时用newroot账户登录数据库。
GRANT SELECT,INSERT,UPDATE,DELETE ON tt.* TO tt@’localhost’ IDENTIFIED BY ‘Asxz!@#9’;(该命令是在MySQL数据库中授予用户 tt 权限,允许该用户具有对 tt 数据库的 SELECT、INSERT、UPDATE 和 DELETE 操作权限。用户验证信息为用户名 tt 和密码 Asxz!@#9。用户只能在本地主机(localhost)上进行操作。)
FLUSH PRIVILEGES;(重新加载授权表以确保任何更改都被生效。)
SHOW GRANTS FOR tt@"localhost";(显示在本地主机上访问tt数据库时授予tt用户的权限)
(4)赋予tt权限
(5)切换到tt用户,登录密码为Asxz!@#9,可以看到对tt用户具有了查看权限,并且通过写入信息可以确定具有增加数据权限。如图所示。
SHOW DATABASES;
USE tt;
INSERT INTO t (id,name,password) VALUES (1,’t1’,’123456’);
SELECT * FROM t;
(6)运行账户:右击任务栏,选择启动任务管理器。如图所示。
(7)在【详细信息】页面,可以看到mysql服务使以system 权限运行,即windows系统最高权限。如图所示。
(8)需更改为普通用户运行mysql服务:首先添加mysql用户,如图所示。
net user mysql Asxz123q /add
net localgroup users mysql /del
net user mysql
(9)设置目录权限,进入C盘,右击MYSQL安装目录MySQL【属性】选项。如图所示。
(10)单击【安全】选项卡,然后单击【编辑】按钮,在弹出的对话框中,单击【添加】按钮,弹出【选择用户或组】对话框,在【输入对象名称来选择】配置模块中输入mysql,然后单击【检查名称】按钮,自动补全信息后,单击【确定】按钮,完成配置。如图所示。
(11)权限保持默认,单击【应用】和【确定】按钮。如图所示。
(12)进入 MYSQL目录同样的方式编辑DATA目录,选中 mysql用户后,单击【编辑】按钮,弹出【data的权限】对话框,修改该用户的权限,选中mysql用户后勾选修改与写入权限,单击【应用】和【确定】按钮。给mysql帐号读写权限。如图所示。
(13)services.msc 设置运行账户,单击【开始】→【Windows系统】→【运行】菜单,如图所示。
(14)输入services.msc 并单击【确定】按钮,调出【服务】对话框。如图所示。
(15)找MySQL服务,并右击该服务,在弹出的菜单中单击【属性】选项。如图所示。
(16)在弹出的对话框中,单击【登录】选项卡,【此账户】输入mysql,并输入密码,密码为前边实验步骤中设置的密码Asxz123q,设置完成后,单击【确定】按钮。如图所示。
(17)如有提示已授权弹窗直接点击【确定】按钮即可
(18)提示需要重新启动服务才可生效,点击确定。然后重启服务。
(19)右击MySQL服务,在弹出的菜单中点击【重新启动】选项。如图所示。
(20)返回任务管理器,可以看到mysql服务已经更换为普通用户运行。如图所示。
(21)可信任ip地址控制:只允许可信任的ip访问数据库,降低风险。在授权过程中,ip若是%代替,则表明任意主机均可登录。这里不再演示。
select user,host from mysql.user;
用于从mysql.user表中选择用户和主机。
GRANT ALL PRIVILEGES ON *.* TO ‘可信任用户’@‘可信任ip’ IDENTIFIED BY ‘密码’ WITH GRANT OPTION;
该命令是授予一个受信任的用户在所有数据库和表上拥有所有权限的命令,该用户的IP地址也是受信任的,并且需要设置一个密码。其中,'可信任用户'是指该用户的用户名,'可信任ip'是指该用户的IP地址,'密码'是指该用户的密码。WITH GRANT OPTION选项允许该用户授予其他用户权限。
(22)连接数限制:通过命令可以查看当前连接数量最高为151。如图所示。
show variables like ‘max_connections’;
(23)修改C:\MySQL\MySQL Server 5.7\my.ini文件,重启服务。重新查询可以看到最大连接数已修改。如图所示。
# My.ini 修改下列信息
[mysqld]
Max_connections =30
(24)重启服务
# 重启mysql
net stop mysql57
net start mysql57
(25)修改并验证
5. 日志审核
(1)除了商业版的审计插件外,常见的还有三类审计插件Percona Audit Log Plugin、MariaDB Audit Plugin、McAfee MySQL Audit Plugin。这几个插件功能上大同小异,只是展示的内容和格式略有不同。
(2)以MariaDB Audit Plugin为例,介绍如何采用插件的方式实现对Mysql数据的审计。
(3)默认插件目录:如图所示。
show variables like 'plugin_dir';
(4)把C:\tools\文件夹下的server_audit.dll复制到对应的mysql插件库中C:\MySQL\MySQL Server 5.7\lib\plugin。如图所示。
(5)执行install安装命令。如图所示。
install plugin server_audit soname 'server_audit.dll';
(6)验证是否安装成功。如图所示。
show variables like '%audit%';
server_audit_logging:启动或关闭审计;
server_audit_events:指定记录事件的类型,可以用逗号分隔的多个值(connect,query,table) ,默认为空代表审计所有事件;
server_audit_incl_users:指定哪些用户的活动将记录,默认审计所有用户,该变量比server_audit_excl_users优先级高;
server_audit_excl_users:指定哪些用户行为不记录;
server_audit_output_type:指定日志输出类型,可为SYSLOG或FILE,缺省输出至审计文件。
(7)开启审计。如图所示。
set global server_audit_logging=on;
(8)由于是验证测试,其余参数都按默认设置。
(9)执行一些数据库操作:如图所示。
INSERT INTO tt.t (id,name,password) VALUES (2,’s2’,’12345600’);
(10)查看审计记录日志:日志文件server_audit.log默认在data目录下。可以看到刚执行的命令已经被记录。如图所示。(记录在一行,以时间记录分隔)
6. 备份
(1)通过mysqldump进行数据库备份,若账户具有其他远程主机服务的权限,则可以将host参数更改为远程主机ip,进行远程备份。如图所示。
Mysqldump --opt -–user=newroot --password=123456 --host=127.0.0.1 --events “tt” > C:\tt.sql
(2)通过计划任务实现自动备份,创建脚本,其功能为备份tt数据库。如图所示。
rem ******Backup MySQL Start******
@echo off
::设置时间变量
set "Ymd=%date:~0,4%%date:~5,2%%date:~8,2%"
::创建存储的文件夹
if not exist "C:\mysql_backup" md "C:\mysql_backup"
::执行备份操作
mysqldump --opt --user=newroot --password=123456 --host=127.0.0.1 --default-character-set=utf8 --events "tt" > C:\mysql_backup\backup_demo_%Ymd%.sql
::删除两周前的备份数据
forfiles /p "C:\mysql_backup" /m backup_*.sql -d -14 /c "cmd /c del /f @path"
@echo on
rem ******Backup MySQL End******
(3)打开任务计划:单击【开始】→【Windows管理工具】→【任务计划程序】菜单,打开计划任务程序。如图所示。
(4)单击【任务计划程序】右侧的【创建基本任务】链接。弹出【创建基本任务向导】对话框,首先进入【创建基本任务】步骤,【名称】输入mysql.backup,然后单击【下一步】按钮。如图所示。
(5)进入【触发器】设置步骤,选择备份周期为【每周】。然后单击【下一步】按钮。如图所示。
(6)因为本次仅做演示,所以默认下一步即可。在实际环境中,需根据需求进行调整,一般备份时间选择在深夜,因此时访问量人少。如图所示。
(7)进入【操作】步骤,保持默认选择,单击【下一步】按钮。如图所示。
(8)进入【启动程序】设置步骤,选择刚创建backup.bat 脚本文件,然后单击【下一步】按钮。如图所示。
(9)进入【完成】步骤,确保配置无误后,单击【完成】按钮。如图所示。
(10)在任务计划程序库中,可以看到刚创建的计划任务。如图所示。
(11)手动更改计算机当前时间或直接运行bat脚本。可以看到备份成功。如图所示。
7. 补丁
满足业务正常运行的前提下,安装新版本,修补漏洞。
(1)修复mysql漏洞,一般升级对应的小版本官方发布最新的小版本即可。
(2)注意查看对应数据库版本及操作平台信息及升级后可能触发的BUG信息。
(3)确认当前业务使用,可能存在封装好无法改变的应用的脚本触发到BUG信息。
【实验结果】
- mysql无匿名用户。
- 无法创建弱口令用户。
- 数据库操作被记录。
【实验思考】
如何通过审计插件记录数据库的操作?