当前位置:   article > 正文

MySQL安全加固基线_mysql基线加固

mysql基线加固

1-系统安全配置

1.1 数据库存放位置检查

在linux系统中,数据库文件不宜存放在 /,/var,/usr目录内,执行以下命令进行检查

  1. mysql> select @@datadir;
  2. # 或者
  3. mysql> show variables where variable_name='datadir';

加固方法

  1. # 设置指定安全的路径
  2. mysql> set global datadir='路径' ;
  3. # 或者修改配置文件my.cnf(linux)或my.init(windows)中的datadir值
  4. datadir='路径'

1.2 以最小权限账号运行mysql

  • windows系统:打开任务管理器,查看运行mysql的是什么权限账号,不能是administrator
  • linux系统: 不是是高权限账号(root)运行mysql,也不可以是在高权限用户组内
  1. # ps命令查看进程, grep命令过滤结果
  2. ps -ef | grep mysql

加固方法

  1. # 1. 创建低权限账号和组
  2. groupadd mysql
  3. useradd -r -g mysql mysql
  4. # 2. 给新建账号添加密码
  5. passwd mysql
  6. # 3. 修改MYSQL安装目录的权限(提前关闭mysql服务)
  7. chown -R mysl.mysql mysql安装路径
  8. # 4. 读写执行权限最小化755
  9. chmod 755 mysql安装根路径
  10. chmod 755 mysql安装后执行目录(bin)
  11. chmod 755 mysql安装后lib库(libexec)
  12. chmod -R go-rwx mysql数据存储目录(data)
  13. # 5.重启mysql服务即可
  14. service mysqld start

使用其它Linux用户启动mysqld,增加user选项指定/etc/my.cnf选项文件或服务器数据目录的my.cnf选项文件中的[mysqld]组的用户名。

  1. vim /etc/my.cnf
  2. [mysqld]
  3. user=mysql

1.3 禁用mysql命令行历史记录

查看系统中是存在.mysql_history文件,若存在则需要加固

find / -name ".mysql_history"

加固方法

  1. echo "export MYSQL_HISTORY=dev/null" >> /etc/profile
  2. ln -s /dev/null .mysql_history文件路径
  3. rm -r .mysql_history文件路径

1.4 检查MYSQL_PWD环境变量

使用如下命令,查看MYSQL_PWD环境变量是否设置了敏感信息

grep MYSQL_PWD /proc/*/environ

2-密码安全配置

2.1 空密码检查

  1. # 检查是否存在密码长度为0的用户
  2. mysql> select user,host from mysql.user where length(authentication_string) = 0;
  3. # 通过mysql.user系统表查看全部数据库用户状态
  4. mysql> select user,host,authentication_string,password_lifetime,account_locked from mysql.user;

2.2 密码复杂度配置

MySQL 系统自带有 validate_password 插件,此插件可以验证密码强度,未达到规定强度的密码不允许被设置。MySQL 5.7 及 8.0 版本默认情况下均不启用该插件。

(1)插件安装检查

进入 MySQL 命令行,通过 show plugins 或者查看 validate_password 相关参数可以判断是否已安装此插件

  1. # 插件安装检查,返回为空表示未安装
  2. mysql> show variables like 'validate%';

(2)validate_password 插件安装

  1. # 安装插件
  2. mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';
  3. # 查看 validate_password 相关参数
  4. mysql> show variables like 'validate%';
  5. +--------------------------------------+--------+
  6. | Variable_name | Value |
  7. +--------------------------------------+--------+
  8. | validate_password_check_user_name | ON |
  9. | validate_password_dictionary_file | |
  10. | validate_password_length | 8 |
  11. | validate_password_mixed_case_count | 1 |
  12. | validate_password_number_count | 1 |
  13. | validate_password_policy | MEDIUM |
  14. | validate_password_special_char_count | 1 |
  15. +--------------------------------------+--------+
  16. 7 rows in set (0.00 sec)

(3)参数释意

  1. 1validate_password_policy
  2. 代表密码策略,默认是MEDIUM 可配置的值有以下:
  3. 0 or LOW 仅需需符合密码长度(由参数validate_password_length指定)
  4. 1 or MEDIUM 满足LOW策略,同时还需满足至少有1个数字,小写字母,大写字母和特殊字符
  5. 2 or STRONG 满足MEDIUM策略,同时密码不能存在字典文件(dictionary file)中
  6. 2validate_password_dictionary_file
  7. 用于配置密码的字典文件,当validate_password_policy设置为STRONG时可以配置密码字典文件,字典文件中存在的密码不得使用。
  8. 3validate_password_length
  9. 用来设置密码的最小长度,默认值是8
  10. 4validate_password_mixed_case_count
  11. validate_password_policy设置为MEDIUM或者STRONG时,密码中至少同时拥有的小写和大写字母的数量,默认是1最小是0;默认是至少拥有一个小写和一个大写字母。
  12. 5validate_password_number_count
  13. validate_password_policy设置为MEDIUM或者STRONG时,密码中至少拥有的数字的个数,默认1最小是0
  14. 6validate_password_special_char_count
  15. validate_password_policy设置为MEDIUM或者STRONG时,密码中至少拥有的特殊字符的个数,默认1最小是0

(4)密码复杂度策略设置

  1. # 设置密码长度至少10
  2. mysql> set global validate_password_length = 10;
  3. Query OK, 0 rows affected (0.00 sec)

(5)配置文件写入

如果想让密码复杂度策略永久生效,可以在 /etc/mysql/mysql.conf.d/mysqld.cnf 文件中写入如下配置

  1. [mysqld]
  2. plugin-load = "validate_password.so"
  3. validate-password = FORCE_PLUS_PERMANENT
  4. validate_password_length = 8
  5. validate_password_policy = 1
  6. validate_password_mixed_case_count = 1
  7. validate_password_number_count = 1
  8. validate_password_special_char_count = 1

2.3 密码有效期检查

(1)设置全局过期策略

  1. # 运行中临时生效
  2. mysql> SET GLOBAL default_password_lifetime = 90;
  3. Query OK, 0 rows affected (0.01 sec)
  4. # 修改配置文件使得永久生效
  5. [mysqld]
  6. default_password_lifetime = 90
  7. # 查询全局密码过期时间
  8. mysql> show global variables like 'default_password_lifetime';

(2)设置单个用户密码过期策略

  1. # 通过mysql.user系统表查看全部数据库用户状态
  2. mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
  3. # 设置user1用户密码立即过期
  4. mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE;
  5. # 设置user1用户密码永不过期
  6. mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE NEVER;
  7. # 设置user1用户密码90天过期
  8. mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;
  9. # 设置user1用户密码使用全局密码过期策略
  10. mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE DEFAULT;

3-用户安全配置

3.1 远程管理限制

(1)原则上,应当禁止远程登录(至少要禁止root直接远程登录数据库)

执行以下SQL语句检查 host 字段是否仅为 127.0.0.1 或 localhost 或 ::1

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

(2)其它用户如需远程连接,应做访问范围限制

执行以下SQL语句检查是否存在任意IP登录的用户

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

(3)远程管理用户配置方法

<password> 指定远程连接时使用的密码,与本地密码可不同(但需符合密码复杂度要求)

  1. mysql> GRANT ALL PRIVILEGES ON <databases-name>.* TO 'user'@'<ip>' IDENTIFIED BY '<password>' WITH GRANT OPTION;
  2. mysql> FLUSH PRIVILEGES;
  3. # 例如:给teacher用户分配student数据库,只允许192.168.56.%网段远程连接并设置口令为Admin123
  4. mysql> GRANT ALL PRIVILEGES ON student.* TO 'teacher'@'192.168.56.%' IDENTIFIED BY 'Admin123' WITH GRANT OPTION;
  5. mysql> FLUSH PRIVILEGES;

3.2 删除默认数据库和用户

  1. mysql> show databases;
  2. mysql> drop database test; #删除数据库test
  3. mysql> use mysql;
  4. mysql> delete from db; #删除存放数据库的表信息,因为还没有数据库信息。
  5. mysql> delete from user where not (user='root'); #删除初始非root的用户
  6. mysql> delete from user where user='root' and password=''; #删除空密码的root尽量重复操作
  7. mysql> flush privileges; #强制刷新内存授权表。

3.3 特权账号检查

user表和db表中存放着可以授予数据库用户的权限,确保只有管理员账号才能访问所有数据库

执行如下SQL语句, 确保返回结果只能是数据库管理员账号

  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');
  2. 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') OR (Create_priv = 'Y') OR (Drop_priv = 'Y'));

3.4 限制非管理员用户的权限

user表中的权限列有:

  1. file_priv:表示是否允许用户读取数据库所在主机的本地文件;
  2. Process:表示是否允许用户查询所有用户的命令执行信息;
  3. Super_priv:表示用户是否有设置全局变量、管理员调试等高级别权限;
  4. Shutdown_priv:表示用户是否可以关闭数据库;
  5. Create_user_priv:表示用户是否可以创建或删除其他用户;
  6. Grant_priv:表示用户是否可以修改其他用户的权限;

应确保只有数据库管理员才有上述权限,使用如下sql语句查看拥有各个权限的数据库账号,确保查询结果中不存在非管理员用户

  1. mysql> select user, host from mysql.user where File_priv = 'Y';
  2. mysql> select user, host from mysql.user where Process_priv = 'Y';
  3. mysql> select user, host from mysql.user where Process_priv = 'Y';
  4. mysql> SELECT user, host FROM mysql.user WHERE Shutdown_priv = 'Y';
  5. mysql> SELECT user, host FROM mysql.user WHERE Create_user_priv = 'Y';
  6. mysql> SELECT user, host FROM mysql.user WHERE Grant_priv = 'Y';
  7. mysql> SELECT user, host FROM mysql.db WHERE Grant_priv = 'Y';

如果存在非管理员用户,可以使用如下命令进行权限回收,其中<user>为上述查询到的非管理员用户

  1. mysql> REVOKE FILE ON *.* FROM '<user>';
  2. mysql> REVOKE PROCESS ON *.* FROM '<user>';
  3. mysql> REVOKE SUPER ON *.* FROM '<user>';
  4. mysql> REVOKE SHUTDOWN ON *.* FROM '<user>';
  5. mysql> REVOKE CREATE USER ON *.* FROM '<user>';
  6. mysql> REVOKE GRANT OPTION ON *.* FROM <user>;

3.5 控制DML/DDL操作授权

DML/DDL语句包括创建或修改数据库结构的权限,例如insert、update、delete、create、drop和alter语句,在任何数据库中都要控制用户的此类权限,确保只授权给有业务需求的非管理员用户。

在MySQL命令行下执行如下命令进行检查

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'; 

在上述查询结果中,应该具有针对性地为每个用户设置相关数据库权限,使用如下命令进行相关权限的回收,其中<user>为查询到的未授权的用户,host为相关主机,database为相关数据库

  1. mysql> REVOKE SELECT ON <host>.<database> FROM <user>;
  2. mysql> REVOKE INSERT ON <host>.<database> FROM <user>;
  3. mysql> REVOKE UPDATE ON <host>.<database> FROM <user>;
  4. mysql> REVOKE DELETE ON <host>.<database> FROM <user>;
  5. mysql> REVOKE CREATE ON <host>.<database> FROM <user>;
  6. mysql> REVOKE DROP ON <host>.<database> FROM <user>;
  7. mysql> REVOKE ALTER ON <host>.<database> FROM <user>;

4-文件权限配置

4.1 配置数据目录的访问权限

数据目录是mysql数据库存放的位置,在MySQL命令行界面下执行如下命令:

mysql> show variables where variable_name = 'datadir'; 

在终端命令行下执行如下命令:

  1. # <datadir>是上述命令的执行结果
  2. ls -l <datadir>/.. | egrep "^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql"

若存在问题,执行如下命令进行加固

  1. chmod 700 <datadir>
  2. chown mysql:mysql <datadir>

4.2 配置二进制日志文件的权限

mysql的运行会产生很多日志,例如二进制日志、错误日志、慢查询日志等等,MySQL命令行下执行如下命令:

mysql> show variables like 'log_bin_basename';

在终端命令行执行如下命令:

ls <log_bin_basename>.*

对于发现的每一个文件,执行如下命令,根据输出确认日志文件的权限设置是否存在问题。

ls -l <log_bin_basename.nnnnn> | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 

若存在问题,对于每个日志文件,修改其权限和属组如下:

  1. chmod 660 <log file>
  2. chown mysql:mysql <log file>

4.3 配置错误日志文件的权限

在MySQL命令行下执行如下命令:

mysql> show variables like 'log_error';

在终端命令行执行如下命令:

ls <log_error>.*

对于发现的每一个文件,执行如下命令,根据输出确认日志文件的权限设置是否存在问题。

ls -l <log_error> | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 

若存在问题,对于每个日志文件,修改其权限和属组如下:

  1. chmod 660 <log file>
  2. chown mysql:mysql <log file>

4.4 配置慢查询日志文件的权限

在MySQL命令行下执行如下命令:

mysql> show variables like 'slow_query_log_file';

在终端命令行执行如下命令:

ls <slow_query_log_file>.*

对于发现的每一个文件,执行如下命令,根据输出确认日志文件的权限设置是否存在问题。

ls -l <slow_query_log_file> | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 

若存在问题,对于每个日志文件,修改其权限和属组如下:

  1. chmod 660 <log file>
  2. chown mysql:mysql <log file>

4.5 配置通用日志文件的权限

在MySQL命令行下执行如下命令:

mysql> show variables like 'general_log_file';

在终端命令行执行如下命令:

ls <general_log_file>.*

对于发现的每一个文件,执行如下命令,根据输出确认日志文件的权限设置是否存在问题。

ls -l <general_log_file> | egrep "^-[r|w]{2}-[r|w]{2}----\s*.*$" 

若存在问题,对于每个日志文件,修改其权限和属组如下:

  1. chmod 660 <log file>
  2. chown mysql:mysql <log file>

4.6 配置审计日志文件的权限

在MySQL命令行下执行如下命令:

mysql> show global variables where variable_name =  'audit_log_file';

在终端命令行执行如下命令,根据输出确认日志文件的权限设置是否存在问题。

ls -l <audit_log_file> | egrep "^-rw[-x]rw[-x][-r][-w][-x][ \t]*[0-9][ \t]*mysql[\t]*mysql.*$"

若存在问题,对于每个日志文件,修改其权限和属组如下:

  1. chmod 660 <audit_log_file>
  2. chown mysql:mysql <audit_log_file>

5-入侵防护

5.1 设置连接超时时间

  1. # 查看空闲连接超时时间
  2. mysql> SHOW GLOBAL VARIABLES LIKE '%timeout%'
  3. # 修改空闲连接超时时间
  4. mysql> SET GLOBAL wait_timeout=1800

6-审计和日志

6.1 开启错误日志审计功能

错误日志包括数据库运行和停止过程中的一系列活动信息,有助于分析数据库运行过程中的一些异常活动,一般情况下需要开启错误日志记录功能,使用如下命令查询:

mysql> SHOW variables LIKE 'log_error';

确保返回结果为非空,如果为空,需要在mysql数据库配置文件中增加如下配置

  1. # 在/etc/my.cnf加入配置
  2. [mysqld_safe]
  3. log-error=log文件路径

6.2 确保日志存放在非系统区域

使用如下命令进行查询:

mysql> SELECT @@global.log_bin_basename;

确保返回结果不是如下路径:/、/var、/usr

6.3 关闭原始日志功能

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

  1. [mysqld_safe]
  2. Log-raw = OFF
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/954579
推荐阅读
相关标签
  

闽ICP备14008679号