MySQL安全加固基线

1-系统安全配置

1.1 数据库存放位置检查

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

mysql> select @@datadir;
# 或者
mysql> show variables where variable_name='datadir';

加固方法

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

1.2 以最小权限账号运行mysql

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

加固方法

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

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

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

1.3 禁用mysql命令行历史记录

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

find / -name ".mysql_history"

加固方法

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

1.4 检查MYSQL_PWD环境变量

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

grep MYSQL_PWD /proc/*/environ

2-密码安全配置

2.1 空密码检查

# 检查是否存在密码长度为0的用户
mysql> select user,host from mysql.user where length(authentication_string) = 0;
# 通过mysql.user系统表查看全部数据库用户状态
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 相关参数可以判断是否已安装此插件

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

(2)validate_password 插件安装

# 安装插件
mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';

# 查看 validate_password 相关参数
mysql> show variables like 'validate%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | ON     |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.00 sec)

(3)参数释意

1、validate_password_policy
代表密码策略,默认是MEDIUM 可配置的值有以下:
    0 or LOW 仅需需符合密码长度(由参数validate_password_length指定)
    1 or MEDIUM 满足LOW策略,同时还需满足至少有1个数字,小写字母,大写字母和特殊字符
    2 or STRONG 满足MEDIUM策略,同时密码不能存在字典文件(dictionary file)中

2、validate_password_dictionary_file
用于配置密码的字典文件,当validate_password_policy设置为STRONG时可以配置密码字典文件,字典文件中存在的密码不得使用。

3、validate_password_length
用来设置密码的最小长度,默认值是8

4、validate_password_mixed_case_count
当validate_password_policy设置为MEDIUM或者STRONG时,密码中至少同时拥有的小写和大写字母的数量,默认是1最小是0;默认是至少拥有一个小写和一个大写字母。

5、validate_password_number_count
当validate_password_policy设置为MEDIUM或者STRONG时,密码中至少拥有的数字的个数,默认1最小是0

6、validate_password_special_char_count
当validate_password_policy设置为MEDIUM或者STRONG时,密码中至少拥有的特殊字符的个数,默认1最小是0

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

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

(5)配置文件写入

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

[mysqld]
plugin-load = "validate_password.so"
validate-password = FORCE_PLUS_PERMANENT
validate_password_length = 8 
validate_password_policy = 1 
validate_password_mixed_case_count = 1 
validate_password_number_count = 1 
validate_password_special_char_count = 1 

2.3 密码有效期检查

(1)设置全局过期策略

# 运行中临时生效
mysql> SET GLOBAL default_password_lifetime = 90;
Query OK, 0 rows affected (0.01 sec)

# 修改配置文件使得永久生效
[mysqld]
default_password_lifetime = 90

# 查询全局密码过期时间
mysql> show global variables like 'default_password_lifetime';

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

# 通过mysql.user系统表查看全部数据库用户状态
mysql> select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;

# 设置user1用户密码立即过期
mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE;

# 设置user1用户密码永不过期
mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE NEVER;

# 设置user1用户密码90天过期
mysql> ALTER USER 'user1'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;

# 设置user1用户密码使用全局密码过期策略
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> 指定远程连接时使用的密码,与本地密码可不同(但需符合密码复杂度要求)

mysql> GRANT ALL PRIVILEGES ON <databases-name>.* TO 'user'@'<ip>' IDENTIFIED BY '<password>' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;

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

3.2 删除默认数据库和用户

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

3.3 特权账号检查

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

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

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');
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表中的权限列有:

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

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

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

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

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

mysql> SELECT user, host FROM mysql.user WHERE Shutdown_priv = 'Y';

mysql> SELECT user, host FROM mysql.user WHERE Create_user_priv = 'Y';

mysql> SELECT user, host FROM mysql.user WHERE Grant_priv = 'Y';

mysql> SELECT user, host FROM mysql.db WHERE Grant_priv = 'Y'; 

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

mysql> REVOKE FILE ON *.* FROM '<user>';

mysql> REVOKE PROCESS ON *.* FROM '<user>';

mysql> REVOKE SUPER ON *.* FROM '<user>';

mysql> REVOKE SHUTDOWN ON *.* FROM '<user>';

mysql> REVOKE CREATE USER ON *.* FROM '<user>';

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为相关数据库

mysql> REVOKE SELECT ON <host>.<database> FROM <user>;

mysql> REVOKE INSERT ON <host>.<database> FROM <user>;

mysql> REVOKE UPDATE ON <host>.<database> FROM <user>;

mysql> REVOKE DELETE ON <host>.<database> FROM <user>;

mysql> REVOKE CREATE ON <host>.<database> FROM <user>;

mysql> REVOKE DROP ON <host>.<database> FROM <user>;

mysql> REVOKE ALTER ON <host>.<database> FROM <user>; 

4-文件权限配置

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

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

mysql> show variables where variable_name = 'datadir'; 

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

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

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

chmod 700 <datadir>
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*.*$" 

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

chmod 660 <log file>
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*.*$" 

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

chmod 660 <log file>
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*.*$" 

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

chmod 660 <log file>
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*.*$" 

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

chmod 660 <log file>
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.*$"

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

chmod 660 <audit_log_file>
chown mysql:mysql <audit_log_file>

5-入侵防护

5.1 设置连接超时时间

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

6-审计和日志

6.1 开启错误日志审计功能

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

mysql> SHOW variables LIKE 'log_error';

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

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

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

使用如下命令进行查询:

mysql> SELECT @@global.log_bin_basename;

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

6.3 关闭原始日志功能

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

[mysqld_safe]
Log-raw = OFF
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL安全配置基线是指通过一系列的SQL语句对MySQL进行安全配置,以提高数据库的安全性。以下是一种可能的MySQL安全配置基线SQL: 1. 创建一个新的管理员账户,并设置强密码: CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin_password'; GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; 2. 移除不必要的默认账户: DELETE FROM mysql.user WHERE User=''; 3. 禁用匿名账户: DELETE FROM mysql.user WHERE User=''; 4. 限制外部访问: UPDATE mysql.user SET Host='localhost' WHERE User='root'; 5. 禁用远程Root登录: UPDATE mysql.user SET Super_priv='N' WHERE User='root'; 6. 禁止root账户从非本地网络登录: UPDATE mysql.user SET Host='127.0.0.1',Host='::1' WHERE User='root'; 7. 配置密码策略: SET GLOBAL validate_password.policy=LOW; SET GLOBAL validate_password.length=6; SET GLOBAL validate_password.number_count=0; SET GLOBAL validate_password.special_char_count=0; SET GLOBAL validate_password.mixed_case_count=0; 8. 限制错误登录次数: CREATE DATABASE IF NOT EXISTS mysql_fail2ban; USE mysql_fail2ban; CREATE TABLE IF NOT EXISTS failed_logins (ip VARCHAR(15) NOT NULL, attempts INT DEFAULT 0, last_attempt TIMESTAMP); GRANT INSERT, SELECT ON mysql_fail2ban.failed_logins TO 'admin'@'localhost'; 这些SQL语句可以帮助你基于MySQL的特定需求来保护数据库免受潜在的安全威胁。请注意,在执行任何安全配置之前,务必备份数据库以防止意外数据丢失。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值