MySQL数据库安全加固方法

MySQL数据库安全加固方法

基本安全原则

  • 选择稳定、无漏洞版本并及时升级更新、打补丁

  • 配置防火墙策略,更改默认端口

  • 避免使用弱口令,定期更新口令

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

具体安全配置

系统层面配置

  • 系统安装时,需要确认没有其他⽤户登录在服务器上。建议在服务器本地安装,不使⽤⽹络远程安装。

  • 数据库版本选择稳定、无漏洞的版本,并及时更新、打补丁

  • 查看系统防火墙或网络安全设备,是否有限制对MySQL数据库的访问

  • 不设置环境变量或确保MYSQL_PWD环境变量未设置敏感信息

  • 禁止使用命令行历史记录

    Linux系统:
    执行如下命令:
    find / -name ".mysql_history"
    ​
    查看是否存在mysql的历史命令记录文件,如果存在,则需要进行如下加固:
    ​
    (1)删除.mysql_history文件;
    (2)设置环境变量MYSQL_HISTFILE为/dev/null,并添加到shell的初始化脚本中,创建mysql_history到/dev/null的链接:
     ln -s /dev/null $HOME/.mysql_history 

服务器配置

严禁将数据库服务器允许从公⽹直接访问,也严禁将数据库服务器配置公⽹IP或通过⽹络设备映射出公⽹IP。
在局域⽹内限制开放的端口。需要其他额外的端口,需要提出申请,并有⽂档记录。
服务器不应该具备访问外⽹的能⼒(如有必要,可单向访问)。
新的服务器正式投⼊使⽤前,必须经过安全加固。

数据库通信安全

  • 通信加密

    show variables like ‘have_openssl’;
    have_openssl=YES
  • 服务端证书验证

    查看my.cnf文件[Client] 字段,已配置ssl_verify_server_cert参数
  • SSL连接配置

    1.show variables like ‘ssl_cert’;
    2.show variables like ‘ssl_key’;
    3.show variables like ‘ssl_ca’;

⽤户和密码配置

  • 严格限制Mysql帐户,使用专用的最小权限账号运行Mysql数据库进程

  • 重命名root账号

  • 禁止数据库账号共用

  • 控制最高权限只有管理员

    使用如下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'));
    ​
    确保返回结果只能是数据库管理员账号。
  • 限制非管理员用户的权限

    Mysql.user表中的权限列有:
    ​
    file_priv:表示是否允许用户读取数据库所在主机的本地文件;
    ​
    Process:表示是否允许用户查询所有用户的命令执行信息;
    ​
    Super_priv:表示用户是否有设置全局变量、管理员调试等高级别权限;
    ​
    Shutdown_priv:表示用户是否可以关闭数据库;
    ​
    Create_user_priv:表示用户是否可以创建或删除其他用户;
    ​
    Grant_priv:表示用户是否可以修改其他用户的权限;
    ​
    应确保只有数据库管理员才以下权限,使用如下sql语句查看拥有各个权限的数据库账号:
    ​
    select user, host from mysql.user where File_priv = 'Y';
    ​
    select user, host from mysql.user where Process_priv = 'Y';
    ​
    select user, host from mysql.user where Super_priv = 'Y';
    ​
    SELECT user, host FROM mysql.user WHERE Shutdown_priv = 'Y';
    ​
    SELECT user, host FROM mysql.user WHERE Create_user_priv = 'Y';
    ​
    SELECT user, host FROM mysql.user WHERE Reload_priv = 'Y';
    SELECT user, host FROM mysql.db WHERE Grant_priv = 'Y';
    ​
    确保查询结果中不存在非管理员用户。
    ​
    如果存在非管理员用户,使用如下命令进行权限回收:
    ​
    REVOKE FILE ON *.* FROM '';
    ​
    REVOKE PROCESS ON *.* FROM '';
    ​
    REVOKE SUPER ON *.* FROM '';
    ​
    REVOKE SHUTDOWN ON *.* FROM '';
    ​
    REVOKE CREATE USER ON *.* FROM '';
    ​
    REVOKE GRANT OPTION ON *.* FROM ;
    ​
    其中user为上述查询到的非管理员用户。
    ​
  • 合理控制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为相关数据库。
  • 历史命令行密码设置为不可见

     (1)先输入mysql -u admin -p
     
     (2)根据命令行提示输入密码;
     
     而不要在一整条命令中输入密码。
     
     另外要控制mysql配置文件访问权限
  • 删除默认test数据库,测试帐号,空密码、匿名帐号

    bash drop database if exists ${dbname};
    #删除冗余数据库, 如test
    bash drop user ''
    #清除无用用户(没有用户名的用户)
    SELECT user,host FROM mysql.user WHERE 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命令行下执行如下命令:
    ​
    show variables like 'log_bin_basename';
    ​
    在终端命令行执行如下命令:
    ls .*
    对于发现的每一个文件,执行如下命令:
    ls -l  | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 
    ​
    # 根据输出确认日志文件的权限设置是否存在问题。
    ​
    对于每个日志文件,修改其权限和属组如下:
    ​
    chmod 660 
    chown mysql:mysql  
  • 控制数据目录、基准目录的访问权限

    数据目录是mysql数据库存放的位置,在mysql命令行界面下执行如下命令:
    ​
    show variables where variable_name = 'datadir'; 
    ​
    在终端命令行下执行如下命令:
    ​
    ls -l /.. | egrep "^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql"
    ​
    # 其中是第一条命令的执行结果
    ​
    如果存在问题,linux环境下在终端执行如下命令进行加固:
    ​
    chmod 700  #仅MySQL数据库用户有读写权限
    chown mysql:mysql  
    ​
    同理控制基准目录权限 ,仅DBA和数据库用户可访问
  • 控制错误日志文件的权限

    Mysql命令行下执行如下命令:
    ​
    show variables like 'log_error';
    ​
    在终端命令行执行如下命令:
    ls .*
    对于发现的每一个文件,执行如下命令:
    ls -l  | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 
    ​
    # 根据输出确认日志文件的权限设置是否存在问题。
    ​
    对于每个日志文件,修改其权限和属组如下:
    ​
    chmod 660 
    chown mysql:mysql 
  • 控制慢查询日志文件的权限

    Mysql命令行下执行如下命令:
    ​
    show variables like 'slow_query_log_file';
    ​
    在终端命令行执行如下命令:
    ls .*
    对于发现的每一个文件,执行如下命令:
    ls -l  | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 
    ​
    根据输出确认日志文件的权限设置是否存在问题。
    ​
    对于每个日志文件,修改其权限和属组如下:
    ​
    chmod 660 
    chown mysql:mysql 
  • 控制通用日志文件的权限

    Mysql命令行下执行如下命令:
    ​
    show variables like 'general_log_file';
    ​
    在终端命令行执行如下命令:
    ls .*
    对于发现的每一个文件,执行如下命令:
    ls -l  | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 
    ​
    # 根据输出确认日志文件的权限设置是否存在问题。
    ​
    对于每个日志文件,修改其权限和属组如下:
    ​
    chmod 660 
    chown mysql:mysql 
  • 控制审计日志文件的权限

    Mysql命令行下执行如下命令:
    ​
    show global variables where variable_name =  'audit_log_file';
    ​
    在终端执行如下命令:
    ls -l  | egrep "^-rw[-x]rw[-x][-r][-w][-x][ \t]*[0-9][ \t]*mysql[
    \t]*mysql.*$"
    ​
    # 根据输出确认日志文件的权限设置是否存在问题。
    ​
    对于每个日志文件,修改其权限和属组如下:
    ​
    chmod 660 
    chown mysql:mysql 

审计和日志

  • 开启错误日志审计功能

    错误日志包括数据库运行和停止过程中的一系列活动信息,有助于分析数据库运行过程中的一些异常活动,一般情况下需要开启错误日志记录功能,使用如下命令查询:
    ​
    SHOW variables LIKE 'log_error';
    ​
    确保返回结果为非空,如果为空,需要在mysql数据库配置文件中增加相关配置
  • 确保日志存放在非系统区域

    日志文件随着数据库的运行会不断增加,如果存放在系统区域,则会影响系统的正常运行,使用如下命令进行查询:
    ​
    SELECT @@global.log_bin_basename;
    ​
    确保返回结果不是如下路径:/、/var、/usr
  • 关闭原始日志功能

    原始日志选项会决定一些敏感信息是否会被明文写进日志中,例如查询日志、慢查询日志、二进制日志,确保数据库配置文件中存在如下配置项:
    ​
    Log-raw = OFF

你可能感兴趣的:(MySQL,安全加固)