【安全基线】-MySQL安全配置规范

1. 概述

1.1 博客背景

苦恼于当前互联网上现拥有的基线资源不具备实时性,适用的版本比较老旧,甚至已逐步被企业淘汰。

文档中的众多配置项在现使用版本的MySQL已不复存在,或是检查加固的命令由于系统的升级已不再适用。

博主本着学习实验的心态,充当互联网优秀资源的搬运者、整合者、二次加工者,写下这篇博客,希望能给那些同我有着相同困扰的安全从业者、DBA、安全运维工程师捎去一丝便利。

1.2 基线目标

通过在系统生命周期不同阶段对目标系统展开各类安全检查,找出不符合基线定义的安全配置项并选择和实施安全措施来控制安全风险,并通过对历史数据的分析获得系统安全状态和变化趋势。

1.3 适用版本

本安全基线的适用版本为:MySQL 5.7 Community Server 社区版本。

MySQL 5.7 Enterprise版本存在额外独有的附加配置项待进一步配置,包括但不限于:

  • 确保audit_log_connection_policy被设置成ERRORS或ALL
  • 确保audit_log_exclude_accounts中设置的内容不会让某些用户的行为逃避审计
  • 确保audit_log_include_accounts中设置为空
  • 确保audit_log_policy设置为LOGINS或更高级别
  • 确保audit_log_statement_policy中设置为ALL
  • 确保audit_log_strategy设置为SYNCHRONOUS或SEMISYNCHRONOUS

1.4 参考标准  

  • 《ISO/IEC 27001:2013 信息技术 安全技术 信息安全管理体系 要求》;
  • 《GB/T 22080-2016 信息技术 安全技术 信息安全管理体系 要求》;
  • 《GB/T 22239-2008信息安全技术 信息系统安全等级保护基本要求》;
  • 《CIS MySQL 5.7 benchmark》

2. 基本安全配置

2.1 安装补丁

名称

补丁安装

实施目的

确保数据库版本为最新并修复已知的安全漏洞

问题影响

系统存在严重的安全漏洞,容易被黑客攻击利用

升级MySQL版本要求重启服务器

系统当前状态

显示当前的数据库版本

mysql> SHOW VARIABLES WHERE Variable_name LIKE "version";

判断依据

查看MySQL官网,比较补丁修复情况

实施步骤

请慎重对数据库系统打补丁,补丁安装应当先在测试机上完成。补丁安装可能导致系统或某些服务无法工作正常。在下载补丁包时,一定要对签名进行核实,防止执行特洛伊木马。

2.2 删除默认安装数据库test

名称

删除默认安装数据库test

说明

MySQL安装时默认创建一个测试数据库test,完全的空数据库,没有任何表,可以删除。

问题影响

测试数据库可以被所有用户访问,并且可以用来消耗系统资源。 删除测试数据库将减少MySQL服务器的攻击面。

检查方法

执行以下SQL语句以检查test数据库是否存在

mysql> SHOW DATABASES LIKE 'test';

参考值

clip_image002[18]

实施步骤

删除test数据库:

mysql>DROP DATABASE "test";

回退方案

备注

5.7及以上版本默认情况下不存在test数据库

2.3 修改root用户名

名称

修改root用户名

说明

MySQL默认用户root应该修改名称,以减小攻击面。

问题影响

防止黑客针对用户名进行密码猜测攻击。

检查方法

执行sql检查数据库是否有默认用户root:

mysql> SELECT user from mysql.user where user='root;

如果有返回行则需要修改

clip_image002[22]

参考值

Empty set (0.00 sec)

实施步骤

mysql> update user set name='newname' where name='oldname';

mysql> flush privileges;

回退方案

2.4 MySQL操作系统账号权限最小化

名称

MySQL操作系统账号权限最小化

说明

MySQL在操作系统上的账号权限最小化有助于减小MySQL数据库漏洞造成的影响。

问题影响

防止黑客利用MySQL漏洞入侵操作系统,造成更大损失。

检查方法

假设MySQL账号为mysql,执行命令

ps -ef | egrep "^mysql.*$"

如果没有返回行,则权限存在问题

参考值

存在返回行

clip_image002[24]

实施步骤

创建一个仅用于运行MySQL和直接相关进程的用户

回退方案

2.5 禁止MySQL链接历史记录

名称

禁止MySQL链接历史记录

说明

MySQL会把客户端登陆的交互执行记录保存在.mysql_history文件中。

问题影响

该记录有可能会暴露登陆过程中的敏感信息。建议删除该记录

检查方法

检查.mysql_history文件是否存在(默认在home下):

find /home -name ".mysql_history"

如果有返回行说明存在.mysql_history文件,建议删除。

参考值

无返回行

实施步骤

1. 如果存在.mysql_history,则删除

rm –f . mysql_history

2. 创建链接,防止.mysql_history再次生成

ln -s /dev/null $HOME/.mysql_history

或采用修改mysql_history的环境变量让他的值等于 /dev/null

2.6 禁止MYSQL_PWD的使用

名称

禁止MYSQL_PWD的使用

说明

MYSQL_PWD是一种用于存储mysql密码的环境变量。

问题影响

以明文形式存储mysql密码,存在安全隐患。

检查方法

检查MYSQL_PWD环境变量是否存在于某个进程中:

grep MYSQL_PWD /proc/*/environ

如果有返回行说明那个进程使用了MYSQL_PWD环境变量。

参考值

无返回行

实施步骤

对使用MYSQL_PWD环境变量变量的脚本和进程,建议不在使用该环境变量。

2.7 禁止MySQL操作系统账号登陆

名称

禁止MySQL操作系统账号登陆

说明

MySQL做系统账号在安装完数据库后,不应该有其他用途。建议禁止该账号登陆操作系统。

问题影响

此举在防止黑客利用MySQL数据库漏洞反射shell有极佳效果。

检查方法

假设MySQL数据库操作系统账号就是mysql,执行下列命令:

getent passwd mysql | egrep "^.*[ \ /bin\ / false| \ / sbin \ / nologin]$"

如果没有返回行则说明存在安全隐患。

参考值

clip_image004[4]

实施步骤

执行下列语句禁止mysql登陆:

usermod -s /sbin/nologin mysql

回退步骤

usermod -s /bin/bash mysql

2.8 更改MySQL默认端口

名称

更改MySQL默认端口

说明

使用默认端口,会更容易被黑客在网络中发现数据库

问题影响

改成其他端口有助于隐藏数据库,防止被黑客入侵。

检查方法

show global variables like 'port';

如果返回是3306,则说明需要修改端口

参考值

除3306以外的任何端口

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

port=XXXX (除3306以外的任何端口)

2. 重启mysql服务

systemctl restart mysqld

回退步骤

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

3. 文件系统权限

3.1 log-bin二进制日志

名称

log-bin二进制日志

说明

log-bin就是binary log,二进制日志文件,这个文件记录了mysql所有的dml操作。

问题影响

限制二进制日志文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查看log-bin日志文件状态及相关配置

    mysql> show variables like 'log_bin%';

clip_image002[26]

2. 检查日志文件的权限是660并且属于mysql:mysql

参考值

  • log_bin=ON
  • log_bin_basename=/var/lib/mysql/mysql-bin
  • log_bin_index=/var/lib/mysql/mysql-bin.index
  • 文件权限=660
  • 文件所属mysql:mysql

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

log_bin= /var/lib/mysql/mysql-bin   // 5.7默认未开启binlog

server-id=1 //随机指定不和其他集群中机器重名的字符串,如果只有一台机器,那就可以随便指定了

2. 重启mysql服务

systemctl restart mysqld

3. chmod 660 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

备注

备注:自动设置log_bin_index文件为你指定的文件名后跟.index

5.7版本若不添加server-id,重启mysql服务会报错

8.0版本默认情况下已开启binlog,文件权限为640,所属mysqlmysql

3.2 log-err错误日志

名称

log-err错误日志

说明

错误日志记录了MySQL Server每次启动和关闭的详细信息以及运行过程中所有较为严重的警告和错误信息

问题影响

限制日志文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查看log-err日志文件状态及相关配置

mysql> show global variables like 'log_error';

clip_image004[6]

2. 检查日志文件的权限是660并且属于mysql:mysql

参考值

  • log_error=/var/log/mysqld.log //默认开启log_error,默认径/var/log/mysqld.log
  • 文件权限=660
  • 文件所属mysql:mysql

实施步骤

chmod 660 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

3.3 log-slow-queries慢查询日志

名称

log-slow-queries慢查询日志

说明

它用来记录在MySQL中响应时间超过阀值(long_query_time)的语句

问题影响

限制日志文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查看log-slow-queries慢查询日志文件状态及相关配置

mysql> show variables like '%slow_query_log_file%';

clip_image006[4]

2. 检查日志文件的权限是660并且属于mysql:mysql

参考值

  • slow_query_log=ON //默认为OFF
  • log-slow-queries= /var/lib/mysql/localhost-slow.log //默认路径
  • 文件权限=660
  • 文件所属mysql:mysql

实施步骤

1. 执行SQL语句:mysql> set global slow_query_log = on; //开启慢查询日志

2. chmod 660 <file_name>

3. chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

3.4 relay-log中继日志

名称

relay-log中继日志

说明

MySQL进行主主复制或主从复制的时候会在home目录下面产生相应的relay log

问题影响

限制日志文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查看中继日志文件状态及相关配置

mysql> show variables like 'relay_log_basename';

clip_image008[4]

2. 检查日志文件的权限是660并且属于mysql:mysql

参考值

  • relay_log_basename = /var/lib/mysql/localhost-relay-bin //默认路径
  • 文件权限=660
  • 文件所属mysql:mysql

实施步骤

chmod 660 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

3.5 general query log查询日志

名称

查询日志

说明

记录建立的客户端连接和执行的语句。

问题影响

限制日志文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查看查询日志文件状态及相关配置

mysql> show variables like '%general_log%';

clip_image010

2. 检查日志文件的权限是660并且属于mysql:mysql

参考值

  • general_log=on //默认为off
  • general_log_file = /var/lib/mysql/localhost.log //默认关闭,文件名为主名.log
  • 文件权限=660
  • 文件所属mysql:mysql

实施步骤

1. 执行SQL语句:mysql> set global general_log = on; //开启慢查询日志

2. chmod 660 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

3.6 server-key.pem密钥文件

名称

查询日志

描述

限制密钥文件的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查询密钥文件状态及相关配置

mysql> show variables where variable_name = 'ssl_key';

clip_image012

2. 检查日志文件的权限是400并且属于mysql:mysql

参考值

  • ssl_key = server-key.pem //默认路径
  • 文件权限=400
  • 文件所属mysql:mysql

实施步骤

chmod 400 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

3.7 plugin插件目录

名称

plugin插件目录

描述

限制插件目录的权限将有益于保护数据信息不泄露,或被恶意修改。

检查方法

1. 执行sql查询插件目录状态及相关配置

mysql> show variables where variable_name = 'plugin_dir';

clip_image014

2. 检查日志文件的权限是755,并且属于mysql:mysql

参考值

  • plugin-dir=/usr/lib64/mysql/plugin //默认路径
  • 文件权限=755
  • 文件所属mysql:mysql

实施步骤

chmod 755 <file_name>

chown mysql:mysql <file_name>

回退步骤

将文件权限还原为之前的权限

4. 日志审计

4.1 确保log_raw被设置成off

名称

确保log_raw被设置成off

说明

语句中的密码在写入一般查询日志时会被服务器重写,不会以明文方式记录。

问题影响

如果log-raw被设置成ture,则会记成明文。

检查方法

打开数据库配置文件 /etc/my.cnf,确定log_raw被设置成off

如果是off是安全的,但如果是on则需要修复

参考值

log_raw=OFF

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

log_raw=OFF

2. 重启mysql服务

systemctl restart mysqld

回退步骤

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

4.2 确保log_warnings被设置成2

名称

确保log_warnings被设置成2

说明

log_warnings适用于决定日志中记录的内容的。

问题影响

随着级别的调整会记录更多信息,调整到2有助于通过日志追查安全问题。

检查方法

mysql> SHOW GLOBAL VARIABLES LIKE 'log_warnings';

如果返回值是1需要调整到2

clip_image002[32]

参考值

log_warning=2 //默认为2

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

log_warning=2

2. 重启mysql服务

systemctl restart mysqld

回退步骤

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

MySQL 8.0新特性:

log_warnings 参数调整为log_error_verbosity

5. 安全参数设定

5.1 allow-suspicious-udfs

名称

allow-suspicious-udfs参数设定

描述

该选项控制是否可以载入主函数只有 xxx 符的用户定义函数。默认情况下,该选项被关闭,并且只能载入至少有辅助符的 UDF。

问题影响

关闭allow-suspicious-udfs,可以防止通过共享对象文件加载存在威胁的UDFs函数。

检查方法

查看MySQL配置文件allow-suspicious-udfs参数的设定:cat /etc/my.cnf

确认allow-suspicious-udfs不等于TRUE

参考值

allow-suspicious-udfs=FALSE //默认值为FALSE

实施步骤

1. 修改配置文件vi /etc/my.cnf,删除以下安全参数

allow-suspicious-udfs=TRUE (或者将TRUE改为FALSE,具体效果一样)

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

5.2 local_infile

名称

local_infile参数设定

描述

mysql对本地文件的存取是通过SQL语句来实现,主要是通过LOAD DATA LOCAL INFILE来实现,由local_infile参数决定是否支持LOAD DATA LOCAL INFILE

问题影响

禁用local_infile可以阻止黑客利用sql注入来读取数据库文件,减小黑客给数据库带来的安全损失。

检查方法

l 方法一:

查看MySQL配置文件local_infile参数的设定:cat /etc/my.cnf

确认local_infile不等于ON

l 方法二:

mysql> SHOW VARIABLES WHERE Variable_name = 'local_infile';

clip_image002[39]

参考值

local_infile=0 //默认值为OFF,0代表OFF

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

local_infile=0 // 0代表OFF

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

5.3 skip-grant-tables

名称

skip-grant-tables参数设定

描述

数据库启动的时候 跳跃权限表的限制,不用验证密码,直接登录

问题影响

如果不关闭此参数,所有账号可以不受限制的/免密访问任意数据库。会导敏感数据外泄。

检查方法

查看MySQL配置文件skip-grant-tables参数的设定:cat /etc/my.cnf

确认skip-grant-tables不等于TRUE

参考值

skip-grant-tables=FALSE //默认值为FALSE

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

skip-grant-tables=FALSE

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

这种情况只有在忘记root密码 不得已重启数据库的情况下使用的。现网环境慎用,需要重启数据库,并且安全性也比较难以保证。

5.4 skip-symbolic-links

名称

skip-symbolic-links参数设定

描述

开启skip-symbolic-links可以禁止数据库用户删除或重名数据文件目录之外的文件。

问题影响

多个客户可能会访问同一个数据库,若使用链接文件可能会导致外部客户锁定 MySQL 服务器。

检查方法

l 方法一:

查看MySQL配置文件参数的设定:cat /etc/my.cnf

确认skip_symbolic_links等于YES

l 方法二:

mysql> SHOW variables LIKE 'have_symlink';

确认返回的值为DISABLED.

clip_image004[8]

参考值

skip-symbolic-links=yes //默认值为no

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下安全参数

skip-grant-tables=FALSE

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

5.5 daemon_memcached

名称

daemon_memcached参数设定

描述

InnoDB memcached插件允许用户使用memcached协议访问存储在InnoDB中的数据

问题影响

默认情况下,插件未开启认证,任何人可以利用daemon_memcached来访问或修改一部分数据,给数据库造成信息泄漏的隐患。

检查方法

mysql>SELECT * FROM information_schema.plugins WHERE PLUGIN_NAME='daemon_memcached';

如果有返回行数说明有插件,需要删除

clip_image002[41]

参考值

Empty set (0.00 sec) //默认情况下是禁用的

实施步骤

mysql> uninstall plugin daemon_memcached;

回退方案

5.6 secure_file_priv

名称

secure_file_priv参数设定

描述

secure-file-priv参数用来限制LOAD DATA INFILE or SELECT LOCAL_FILE传到指定目录。

问题影响

secure_file_priv限制客户端可以读取数据文件的路径。secure_file_priv设置合理的值可以有效降低sql注入后黑客读取数据库数据的可能性。

检查方法

mysql> SHOW GLOBAL VARIABLES WHERE Variable_name = 'secure_file_priv' AND Value <>'';

如果有返回内容说明安全,否则需要修复

clip_image002[43]

参考值

secure_file_priv=<path_to_load_directory>

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下参数

secure_file_priv=<path_to_load_directory>

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

  • sure_file_priv的值为null ,表示限制mysqld 不允许导入|导出
  • 当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下
  • 当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制

实施效果:

clip_image004[10]

5.7 sql_mode

名称

Sql_mode参数设定

描述

sql_mode模式有三种,STRICT_TRANS_TABLES是其中一种模式。当执行数据更新操作(如INSERT,UPDATE),MySQL依据是否启用严格的SQL_mode处理非法与丢失的数值。

问题影响

STRICT_TRANS_TABLES模式会检查所有更新的数据,在一定程度可以给入侵者规避检测带来阻碍。

NO_AUTO_CREATE_USER是sql_mode的一个选项,可以阻止grant语句在特定情况下自动创建用户,给数据库带来安全隐患。

检查方法

mysql> SHOW VARIABLES LIKE 'sql_mode';

如果返回的列表中包含STRICT_TRANS_TABLES、NO_AUTO_CREATE_USER 说明安全,否则需要修复

clip_image002[45]

参考值

sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下参数

sql_mode=STRICT_ALL_TABLES,NO_AUTO_CREATE_USER

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

mysql5.0以上版本支持三种sql_mode模式:

ANSI模式

宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。

TRADITIONAL模式

严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事物时,会进行事物的回滚。

STRICT_TRANS_TABLES模式

严格模式,进行数据的严格校验,错误数据不能插入,报error错误。

5.8 disconnect_on_expired_password

名称

disconnect_on_expired_password参数设定

描述

disconnect_on_expired_password是用来控制客户端用失效密码来访问数据库的。

问题影响

关闭这个参数会给数据库带来安全风险。

检查方法

mysql> SHOW GLOBAL VARIABLES like 'disconnect_on_expired_password';

如果有返回的是ON说明安全,否则需要修复

clip_image002[47]

参考值

disconnect_on_expired_password =ON //默认为ON

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下参数

disconnect_on_expired_password =ON

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

5.9 master_info_repository

名称

master_info_repository

描述

master_info_repository设置成table,客户端使用的密码存储在表中

相较于文件系统表中更为安全

检查方法

mysql> SHOW GLOBAL VARIABLES LIKE 'master_info_repository';

如果有返回的是table说明安全,否则需要修复

clip_image002[51]

参考值

master_info_repository=table

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加以下参数

master_info_repository=table

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

mysql 8.0版本级以上默认为table

6. MySQL权限安全

6.1 确保只有管理员账号有所有数据库的访问权限

名称

确保只有管理员账号有所有数据库的访问权限

说明

除了管理员账号,其他用户没必要有所有数据库的访问权限。

问题影响

过高的权限会导致安全问题。

检查方法

mysql> SELECT user, host FROM mysql.user WHERE (Select_priv = 'Y') OR (Insert_priv = 'Y') OR (Update_priv = 'Y') OR (Delete_priv = 'Y') OR (Create_priv = 'Y') OR (Drop_priv = 'Y');

mysql> SELECT user, host FROM mysql.db WHERE db = 'mysql' AND ((Select_priv = 'Y') OR (Insert_priv = 'Y') OR (Update_priv = 'Y') OR (Delete_priv = 'Y') 45 | Page OR (Create_priv = 'Y') OR (Drop_priv = 'Y'));

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

参考值

返回的都是管理员账号

实施步骤

清除非管理员账号的过高部分权限

6.2 非管理员账号File_priv不应该设置成Y

名称

非管理员账号File_priv不应该设置成Y

说明

File_priv权限允许MySQL用户对磁盘进行读写操作

问题影响

黑客很可能利用这一点盗取数据库中敏感数据。

检查方法

mysql> select user, host from mysql.user where File_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image004[12]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE FILE ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT FILE ON *.* TO user@localhost; //<user>为需要增加权限的用户

6.3 非管理员账号Process_priv不应该设置成Y

名称

非管理员账号Process_priv不应该设置成Y

说明

Process_priv权限允许委托账号查看当前正在执行的sql语句

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Process_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image006[8]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE PROCESS ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT PROCESS ON *.* TO user@localhost; //user为需要增加权限的用户

6.4 非管理员账号Super_priv不应该设置成Y

名称

非管理员账号Super_priv不应该设置成Y

说明

super_priv权限允许委托账号执行任意语句,非管理员不应该具备该权限。

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Super_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image008[8]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE SUPER ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT SUPER ON *.* TO user@localhost; //user为需要增加权限的用户

备注

‘mysql.session‘@’localhost’:

插件内部使用来访问服务器。该用户已被锁定,客户端无法连接。

6.5 非管理员账号Shutdown_priv不应该设置成Y

名称

非管理员账号Shutdown_priv不应该设置成Y

说明

Shutdown_priv权限允许委托账号关闭数据库,会造成一定安全隐患。

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Shutdown_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image010[7]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE SHUTDOWN ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT SHUTDOWN ON *.* TO user@localhost; //user为需要增加权限的用户

6.6 非管理员账号Create_user_priv不应该设置成Y

名称

非管理员账号Create_user_priv不应该设置成Y

说明

Create_user_priv权限允许委托账号创建任意用户,会造成一定安全隐患。

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Create_user_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image012[8]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE CREATE USER ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT CREATE USER ON *.* TO user@localhost; //user为需要增加权限的用户

6.7 非管理员账号Grant_priv不应该设置成Y

名称

非管理员账号Grant_priv不应该设置成Y

说明

Grant_priv权限允许委托账号对其他用户赋权,可能会被黑客利用造成一定安全隐患。

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Grant_priv= 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image014[7]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE GRANT ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT GRANT ON *.* TO user@localhost; //user为需要增加权限的用户

6.8 非管理员账号Reload_priv不应该设置成Y

名称

非管理员账号Reload_priv不应该设置成Y

说明

Reload_priv权限可以对本地文件进行操作,可能会被黑客利用造成一定安全隐患

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where Reload_priv= 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image016[4]

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE RELOAD ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT RELOAD ON *.* TO user@localhost; //user为需要增加权限的用户

6.9 非管理员账号repl_slave_priv不应该设置成Y

名称

非管理员账号repl_slave_priv不应该设置成Y

说明

repl_slave_priv用于从主服务器上获得更新的数据。

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> select user, host from mysql.user where repl_slave_priv = 'Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image018

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE REPLICATION ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT REPLICATION ON *.* TO user@localhost; //user为需要增加权限的用户

6.10 确保DML/DDL权限只在特定用户手上

名称

确保DML/DDL权限只在特定用户手上

说明

限制用户有INSERT,SELECT,UPDATE,DELETE,DROP,CREATE和ALTER权限

问题影响

使用超越当前用户权限的权利。可以被攻击者所利用。

检查方法

mysql> SELECT User,Host,Db FROM mysql.db WHERE Select_priv='Y' OR Insert_priv='Y' OR Update_priv='Y' OR Delete_priv='Y' OR Create_priv='Y' OR Drop_priv='Y' OR Alter_priv='Y';

如果返回的都是管理员账号说明安全,否则需要对用户清除权限

clip_image020

参考值

返回的都是管理员账号

实施步骤

mysql> REVOKE XXX ON *.* FROM '<user>’; //<user>为需要撤销权限的用户

回退步骤

mysql> GRANT XXX ON *.* TO user@localhost; //user为需要增加权限的用户

7. 口令策略

7.1 口令复杂度

名称

口令复杂度设置

说明

口令应符合口令策略,要求包含数字、字符、大小写和特殊字符,且长度大于等于8位

问题影响

弱口令容易被恶意攻击者爆破,导致口令被猜解

检查方法

通过msyql环境变量可以查看密码策略的相关参数

mysql> show variables like '%password%';

clip_image002[55]

参考值

  • validate_password.policy=MEDIUM //密码策略,默认为MEDIUM策略
  • validate_password.length=8 //密码最少长度为8位
  • validate_password.mixed_case_count=1 //大小写字符长度,至少1个
  • validate_password.number_count=1 //数字至少1个
  • validate_password.pecial_char_count=1 //特殊字符至少1个

实施步骤

1. 修改配置文件vi /etc/my.cnf,添加安全参数

[mysqld]

plugin-load=validate_password.so

validate_password.policy=1 //密码强度检查级别为MEDIUM

validate-password=FORCE_PLUS_PERMANENT //永久强制使用插件,为阻止该插件在运行时被删除

clip_image004[14]

2. 重启mysql服务

systemctl restart mysqld

回退方案

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

备注

mysql5.7默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位。否则会提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements错误

7.2 口令生存周期

名称

口令生存周期设置(因数据库可用性要求高,不强制启用)

描述

推荐口令最长不超过3个月更改一次口令

问题影响

密码永不过期,无法保证口令的安全性

检查方法

1. 查看全局密码过期的参数设定

mysql> show variables like 'default_password_lifetime';

clip_image006[10]

5.7.11版本后都已经把默认值从360变成了0也就是永不过期了;

2. 查看未设定密码过期策略的用户

select user,host,password_lifetime,password_last_changed,password_expired from mysql.user;

clip_image008[10]

参考值

default_password_lifetime=90 //密码90天过期

实施步骤

l 全局参数设定(因数据库可用性要求高,不强制启用):

1. 修改配置文件vi /etc/my.cnf,添加安全参数

[mysqld]

default_password_lifetime=90

clip_image010[9]

2. 重启mysql服务

systemctl restart mysqld

l 特定用户口令过期设定

mysql> ALTER USER 'XXXX'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

回退方案

l 全局设定:

修改配置前使用以下命令备份配置文件

cp /etc/my.cnf /etc/my.cnf.bak

回退操作:

cp /etc/my.cnf.bak /etc/my.cnf

l 特定用户口令过期设定

mysql> ALTER USER 'XXXX'@'localhost' PASSWORD EXPIRE DEFAULT;

7.3 确保无空口令用户

名称

确认无空口令用户

问题影响

如果密码被设置成空密码,入侵者只要知道密码和主机允许列表,就可以绕过身份验证随意登录数据库,进行违规操作。

检查方法

mysql> SELECT User,host FROM mysql.user WHERE authentication_string='';

没有行数返回说明安全,否则需要配置

参考值

clip_image012[10]

实施步骤

mysql> SET PASSWORD FOR 'user'@'host' = PASSWORD("XXXXXXX");

7.4 确保无匿名账户

名称

确认无匿名账户

问题影响

匿名用户是空的,也没有密码。安全性很差,任意人员都可以利用匿名用户访问数据库。

检查方法

mysql> SELECT user,host FROM mysql.user WHERE user = '';

没有行数返回说明安全,否则需要修复

参考值

Empty set (0.00 sec)

实施步骤

删除匿名用户

7.5 确保用户不允许所有ip访问

名称

确保用户不允许所有ip访问

问题影响

某一数据库用户支持所有ip访问,一旦账号密码泄露,数据库就变得很不安全

检查方法

mysql> SELECT user, host FROM mysql.user WHERE host = '%';

结果集为空说明不存在问题,否则需要修复

参考值

clip_image014[9]

实施步骤

删除匿名用户

 

首次整理编写博客,如有不足之处,江湖大佬多担待;

如果正文的内容存在错误或不合理之处,期待你的指正!

posted @ 2018-05-28 17:59  oumeixi  阅读(6286)  评论(0编辑  收藏  举报