系统安装时,需要确认没有其他⽤户登录在服务器上。
选择稳定的版本,并及时更新到最新版本、打补丁
查看系统防火墙或网络安全设备,是否有限制对MySQL数据库的访问
不设置环境变量或确保MYSQL_PWD环境变量未设置敏感信息
禁用MySQL命令历史记录
删除现在的.mysql_history文件
rm ~/.mysql_history
创建它的软连接
ln -s /dev/null ~/.mysql_history
如果有特殊情况需要打开,重新设置MYSQL_HISTFILE即可:
比如export MYSQL_HISTFILE=~/.mysql_history
系统安装时运行mysql_secure_installation执行相关安全设置
运行mysql_secure_installation会执行几个设置:
a)为root用户设置密码
b)删除匿名账号
c)取消root用户远程登录
d)删除test库和对test库的访问权限
e)刷新授权表使修改生效
使用专用的最小权限账号运行Mysql数据库进程
严禁使用弱口令,严禁共享账号
强密码的设定,需要符合以下标准:
每个账号必须要设密码且密码不能和用户名相同;(必选)
不得出现用户名、真实姓名为公司名称;(必选)
用户密码长度不能低于8位;(必选)
不能使用常用单词;(必选)
不能使用用户相关信息:例如生日、电话号码等等;(可选)
至少由3种字符组成,包含字母、数字、特殊符号在内。(可选)
使用validate_password.so插件,进行安全加固
安装插件:(默认安装了插件后,强度插件就启用了,关闭,需要在配置文件假如相关关闭参数)
mysql>INSTALL PLUGIN validate_password SONAME 'validate_password.so';
配置文件添加部分参数:
[mysqld]
plugin-load=validate_password.so
validate_password_policy=2
validate-password=FORCE_PLUS_PERMANENT
3.以上处理后,就可以测试了:
mysql> SET PASSWORD = PASSWORD('abc');
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> SET PASSWORD = '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E';
Query OK, 0 rows affected (0.01 sec)
相关选项说明:
validate-password=ON/OFF/FORCE/FORCE_PLUS_PERMANENT: 决定是否使用该插件(及强制/永久强制使用)。
validate_password_dictionary_file:插件用于验证密码强度的字典文件路径。
validate_password_length:密码最小长度。
validate_password_mixed_case_count:密码至少要包含的小写字母个数和大写字母个数。
validate_password_number_count:密码至少要包含的数字个数。
validate_password_policy:密码强度检查等级,0/LOW、1/MEDIUM、2/STRONG。
validate_password_special_char_count:密码至少要包含的特殊字符数。
其中,关于validate_password_policy-密码强度检查等级:
0/LOW:只检查长度。
1/MEDIUM:检查长度、数字、大小写、特殊字符。
2/STRONG:检查长度、数字、大小写、特殊字符字典文件。
用户密码过期时间小于等于90天
配置文件中设置
[mysqld]
default_password_lifetime=90
重命名root账号
use mysql
update user set user="新的用户名" where user="root";
select user,host,password from mysql.user; #查看结果
控制最高权限只有管理员
使用如下sql语句:
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');
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') OR (Create_priv = 'Y') OR (Drop_priv = 'Y'));
确保返回结果只能是数据库管理员账号。
合理控制DML/DDL操作授权
DML/DDL语句包括创建或修改数据库结构的权限,例如insert、update、delete、create、drop和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';
上述查询到的用户只能对特定的数据库才有相关的权限,使用如下命令进行相关权限的回收:
REVOKE SELECT ON . FROM ;
REVOKE INSERT ON . FROM ;
REVOKE UPDATE ON . FROM ;
REVOKE DELETE ON . FROM ;
REVOKE CREATE ON . FROM ;
REVOKE DROP ON . FROM ;
REVOKE ALTER ON . FROM ;
其中为查询到的未授权的用户,host为相关主机,database为相关数据库。
权限说明:
file_priv:表示是否允许用户读取数据库所在主机的本地文件;
Process:表示是否允许用户查询所有用户的命令执行信息;
Super_priv:表示用户是否有设置全局变量、管理员调试等高级别权限;
Shutdown_priv:表示用户是否可以关闭数据库;
Create_user_priv:表示用户是否可以创建或删除其他用户;
Grant_priv:表示用户是否可以修改其他用户的权限;
历史命令行密码设置为不可见
(1)先输入mysql -u admin -p
(2)根据命令行提示输入密码;
而不要在一整条命令中输入密码。
另外要控制mysql配置文件访问权限
删除默认test数据库,测试帐号,空密码、匿名帐号
bash drop database if exists ${dbname};
#删除冗余数据库, 如test
bash drop user ''
#清除无用用户(没有用户名的用户)
select user,host from mysql.user
#使用该命令查询是否存在空账号
禁止root远程登录
use mysql;
# 切换到mysql数据库(这是MySQL自带的一个数据库,里面存放着一些root的配置信息);
update user set host = "localhost" where user = "root" and host = "%";
# 修改root用户的host属性,确保其为localhost,这表示只能本地访问(%表示可以远程访问);
flush privileges; #刷新
关闭Old_Passwords
mysql> show variables like ‘%password%’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| old_passwords | OFF | ####这里表明已经关闭了旧密码选项
+—————+——-+
1 row in set (0.00 sec)
secure_auth选项设置
如果客户端采用Old_passwords发起连接请求,如果服务器端设置了secure_auth,则客户端会拒绝连接请求,可以根据安全需求在配置文件中做相应配置。
确保所有用户都要求使用非空密码登录
行如下语句查询是否有用户不需要密码即可登录:
SELECT User,host FROM mysql.user WHERE (plugin IN('mysql_native_password', 'mysql_old_password') AND (LENGTH(Password) = 0 OR Password IS NULL)) OR (plugin='sha256_password' AND LENGTH(authentication_string) = 0);
在MySQL中,提供对本地文件的读取,使用的是load data local infile命令,默认在5.0版本中,该选项是默认打开的,该操作令会利用MySQL把本地文件读到数据库中,然后用户就可以非法获取敏感信息了,如不需要读取本地文件,请关闭。
检查方法
Less /etc/my.cnf
检查[mysqld]部分是否存在local-infile=0。
或者ps –aux查看启动mysql进程是有local-infile=0
控制二进制日志文件的权限
mysql的运行会产生很多日志,例如二进制日志、错误日志、慢查询日志等等,Mysql命令行下执行如下命令:
show variables like 'log_bin_basename';
Linux在终端命令行执行如下命令:
ls <log_bin_basename>.*
对于发现的每一个文件,执行如下命令:
ls -l <log_bin_basename>
# 根据输出确认日志文件的权限设置是否存在问题。
对于每个日志文件,修改其权限和属组如下:
chmod 660 <log file>
chown mysql:mysql <log file>
控制datadir、basedir的访问权限
数据目录是mysql数据库存放的位置,在mysql命令行界面下执行如下命令:
show variables where variable_name = 'datadir';
在终端命令行下执行如下命令:
ls -l <datadir>
如果存在问题,linux环境下在终端执行如下命令进行加固:
chmod 700 <datadir> #仅MySQL数据库用户有读写权限
chown mysql:mysql <datadir>
同理控制basedir权限,仅DBA和数据库用户可访问
控制错误日志文件的权限
Mysql命令行下执行如下命令:
show variables like 'log_error';
在终端命令行执行如下命令:
ls <log_error>.*
对于发现的每一个文件,执行如下命令:
ls -l <log_error>
# 根据输出确认日志文件的权限设置是否存在问题。
对于每个日志文件,修改其权限和属组如下:
chmod 660 <log file>
chown mysql:mysql <log file>
控制慢查询日志文件的权限
Mysql命令行下执行如下命令:
show variables like 'slow_query_log_file';
在终端命令行执行如下命令:
ls <slow_query_log_file>.*
对于发现的每一个文件,执行如下命令:
ls -l <slow_query_log_file>
根据输出确认日志文件的权限设置是否存在问题。
对于每个日志文件,修改其权限和属组如下:
chmod 660 <log file>
chown mysql:mysql <log file>
控制通用日志文件的权限
Mysql命令行下执行如下命令:
show variables like 'general_log_file';
在终端命令行执行如下命令:
ls <general_log_file>.*
对于发现的每一个文件,执行如下命令:
ls -l <general_log_file>
# 根据输出确认日志文件的权限设置是否存在问题。
对于每个日志文件,修改其权限和属组如下:
chmod 660 <log file>
chown mysql:mysql <log file>
控制审计日志文件的权限
Mysql命令行下执行如下命令:
show global variables where variable_name = 'audit_log_file';
在终端执行如下命令:
ls -l <audit_log_file>
# 根据输出确认日志文件的权限设置是否存在问题。
对于每个日志文件,修改其权限和属组如下:
chmod 660 <audit_log_file>
chown mysql:mysql <audit_log_file>
开启审计功能
show variables like '%plugin%'; #查看插件存放位置
+-----------------+--------------------------+
| Variable_name | Value |
+-----------------+--------------------------+
| plugin_dir | /usr/lib64/mysql/plugin/ |
| plugin_maturity | unknown |
+-----------------+--------------------------+
注意:mysql上的审计插件libaudit_plugin.so需要单独下载后安装,mariadb自带审计插件server_audit.so
执行安装命令:
install plugin server_audit SONAME 'server_audit.so';
flush privileges;
修改配置文件:
vim /etc/my.cnf
在[mysqld]下面添加
server_audit=FORCE_PLUS_PERMANENT --防止审计插件被卸载
server_audit_logging=ON --开启审计日志
server_audit_excl_users='z' --不在审计内的用户
server_audit_file_rotate_size=2000000 --审计日志文件轮替限制大小
server_audit_file_rotations=200 --审计轮替日志限制数
server_audit_excl_users='root' --审计在内的用户
server_audit_events='query_ddl,query_dml'; --审计日志事件的操作指令内容
重启数据库使配置生效
错误日志包括数据库运行和停止过程中的一系列活动信息,有助于分析数据库运行过程中的一些异常活动,一般情况下需要开启错误日志记录功能,使用如下命令查询:
SHOW variables LIKE 'log_error';
确保返回结果为非空,如果为空,需要在mysql数据库配置文件中增加相关配置
确保数据存放在非系统区域
随着数据库的运行产生的数据会不断增加,如果存放在系统区域,则会影响系统的正常运行,所以配置datadir时应避开:root('/'),"/var","/usr"
关闭原始日志功能
原始日志选项会决定一些敏感信息是否会被明文写进日志中,例如查询日志、慢查询日志、二进制日志,确保数据库配置文件中存在如下配置项:
Log-raw = OFF
数据库定期备份,并保证至少每周1次的完全备份
定期进行备份和恢复有效性的测试