MySQL数据库安全基线(加固方法)

  • A+
所属分类:安全闲碎

MySQL数据库安全加固方法


基本安全原则

  • 选择稳定版本并及时更新、打补丁

  • 严禁使用弱口令,定期更新口令

  • 严格的权限分配和访问控制



具体安全配置
系统层面配置:
    系统安装时,需要确认没有其他⽤户登录在服务器上。
    选择稳定的版本,并及时更新到最新版本、打补丁
    查看系统防火墙或网络安全设备,是否有限制对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)刷新授权表使修改生效


服务器配置
  • 3306端口及服务不允许暴露到公网。如有特殊业务需求需对外网开放,必须经云安全部审核通讨后,才允许对外网开放。

  • 服务器不应该具备访问外⽹的能⼒(如有必要,可单向访问)。

  • 新的服务器正式投⼊使⽤前,必须经过安全加固。


⽤户和密码配置
  • 使用专用的最小权限账号运行Mysql数据库进程

  • 严禁使用弱口令,严禁共享账号

    • 强密码的设定,需要符合以下标准:

每个账号必须要设密码且密码不能和用户名相同;(必选)不得出现用户名、真实姓名为公司名称;(必选)用户密码长度不能低于8位;(必选)不能使用常用单词;(必选)不能使用用户相关信息:例如生日、电话号码等等;(可选)至少由3种字符组成,包含字母、数字、特殊符号在内。(可选)
    • 使用validate_password.so插件,进行安全加固

安装插件:(默认安装了插件后,强度插件就启用了,关闭,需要在配置文件假如相关关闭参数)mysql>INSTALL PLUGIN validate_password SONAME 'validate_password.so';配置文件添加部分参数:[mysqld]plugin-load=validate_password.sovalidate_password_policy=2validate-password=FORCE_PLUS_PERMANENT3.以上处理后,就可以测试了:mysql> SET PASSWORD = PASSWORD('abc');ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsmysql> 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 mysqlupdate 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 <host>.<database> FROM <user>;   REVOKE INSERT ON <host>.<database> FROM <user>;   REVOKE UPDATE ON <host>.<database> FROM <user>;   REVOKE DELETE ON <host>.<database> FROM <user>;   REVOKE CREATE ON <host>.<database> FROM <user>;   REVOKE DROP ON <host>.<database> FROM <user>;   REVOKE ALTER ON <host>.<database> FROM <user>;   其中<user>为查询到的未授权的用户,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};#删除冗余数据库, 如testbash 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对本地文件存取

在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次的完全备份

  • 定期进行备份和恢复有效性的测试


版权声明:本文为CSDN博主「Lee_Natuo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/Lee_Natuo/article/details/84856377


如果觉得文章对你有帮助,请支持下点击右下角“在看”

MySQL数据库安全基线(加固方法)

本文始发于微信公众号(LemonSec):MySQL数据库安全基线(加固方法)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: