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

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.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 <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};
    #删除冗余数据库, 如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对本地文件存取
在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次的完全备份

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

猜你喜欢

转载自blog.csdn.net/Lee_Natuo/article/details/84856377
今日推荐