# Mysql安全加固

## 1、账户安全

1、查看用户

```
select host, user, authentication_string, plugin from user;
```

2、 禁止Mysql 以管理员账户权限运行

以普通帐户安全运行 mysqld，禁止以管理员帐号权限运行 MySQL 服务。在 /etc/my.cnf 配置文件中进行以下设置。

```
  [mysql.server]
  user=mysql
```

3、 避免不同用户间共享账号

根据实际需求创建用户。

基本语法：create user 用户名 identified by ‘明文密码’;

用户：用户名@主机地址

主机地址：’’ / ‘%’

```
mysql> create user 'user1'@'%' identified by '123456';
Query OK, 0 rows affected (0.07 sec)
```

​

查看mysql.user表中是否存在新增的用户

```
*************************** 2. row ***************************
                    Host: %
                    User: user1
```

4、 删除无关账号

注意：mysql中user是带着host本身的（具有唯一性）

基本语法：drop user 用户名@host;

```
mysql> drop user user2;
Query OK, 0 rows affected (0.05 sec)
```

## 2、口令安全

检查账户默认密码和弱密码。口令长度需要至少八位，并包括数字、小写字母、大写字母和特殊符号四类中的至少两种类型，且五次以内不得设置相同的口令。密码应至少每 90 天进行一次更换。

您可以通过执行以下命令修改密码。

1、 使用专门的修改密码的指令

基本语法：set password for 用户 = password(‘新的明文密码’);

2、 使用更新语句update来修改表

基本语法：update mysql.user set password = password(‘新的明文密码’) where user = ‘’ and host= ‘’;

3、mysql 8.0 之后的版本

ALTER USER 'user1'@'%' IDENTIFIED WITH mysql\_native\_password BY 'mysql\@123';

## 3、授权

在数据库权限配置能力范围内，根据用户的业务需要，配置其所需的最小权限。

1、查看数据库授权情况

```
    mysql> use mysql;
    mysql> select * from user\G
    mysql>select * from db\G
    mysql>select * from host\G
    mysql>select * from tables_priv\G
    mysql>select * from columns_priv\G
```

2、授予权限：grant

将权限分配给指定的用户

基本语法：grant 权限列表 on 数据库/*.表名/* to 用户;

权限列表：使用逗号分隔，但是可以使用all privileges代表全部权限

数据库.表名：可以是单表（数据库名字.表名），可以是具体某个数据库（数据库.*），也可以整库（*.\*）

```
mysql> grant select on mydatabase_backup.class to 'user1'@'%';
Query OK, 0 rows affected (0.07 sec)
```

登陆user1用户查看：

```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydatabase_backup  |
+--------------------+
2 rows in set (0.05 sec)

mysql> use mydatabase_backup;
Database changed
mysql> show tables;
+-----------------------------+
| Tables_in_mydatabase_backup |
+-----------------------------+
| class                       |
+-----------------------------+
1 row in set (0.04 sec)
```

3、取消权限：revoke

权限回收：将权限从用户手中收回

基本语法：revoke 权限列表/all privileges on 数据库/*.表/* from 用户;

```
mysql> revoke all privileges on mydatabase_backup.class from 'user1'@'%';
Query OK, 0 rows affected (0.04 sec)
```

登陆user1用户查看：

```
mysql> show tables;
+-----------------------------+
| Tables_in_mydatabase_backup |
+-----------------------------+
| class                       |
+-----------------------------+
1 row in set (0.04 sec)

mysql> show tables;
ERROR 1044 (42000): Access denied for user 'user1'@'%' to database 'mydatabase_backup'
mysql>
```

4、刷新权限：flush

Flush：刷新，将当前对用户的权限操作，进行一个刷新，将操作的具体内容同步到对应的表中。

基本语法：flush privileges;

```
mysql> flush privileges;
Query OK, 0 rows affected (0.05 sec)
mysql>
```

## 4、开启日志审计功能

数据库应配置日志功能，便于记录运行状况和操作行为。

MySQL服务有以下几种日志类型：

* 错误日志： -log-err
* 查询日志： -log （可选）
* 慢查询日志： -log-slow-queries （可选）
* 更新日志： -log-update
* 二进制日志： -log-bin

找到 MySQL 的安装目录，在 my.ini 配置文件中增加上述所需的日志类型参数，保存配置文件后，重启 MySQL 服务即可启用日志功能。例如：

```
    #Enter a name for the binary log. Otherwise a default name will be used.
    #log-bin=
    #Enter a name for the query log file. Otherwise a default name will be used.
    #log=
    #Enter a name for the error log file. Otherwise a default name will be used.
    log-error=
    #Enter a name for the update log file. Otherwise a default name will be used.
    #log-update=
```

该参数中启用错误日志。如果您需要启用其他的日志，只需把对应参数前面的 “#” 删除即可。

日志查询操作说明

* 执行`show variables like 'log_%';`命令可查看所有的 log。
* 执行`show variables like 'log_bin';`命令可查看具体的 log。

## 5、安装最新补丁

确保系统安装了最新的安全补丁。

注意： 在保证业务及网络安全的前提下，并经过兼容性测试后，安装更新补丁。

## 6、禁止远程访问（如果不需要）

禁止网络连接，防止猜解密码攻击、溢出攻击、和嗅探攻击。

注意： 仅限于应用和数据库在同一台主机的情况。

如果数据库不需要远程访问，可以禁止远程 TCP/IP 连接，通过在 MySQL 服务器的启动参数中添加`--skip-networking`参数使 MySQL 服务不监听任何 TCP/IP 连接，增加安全性。

1、设置用户远程访问

在 mysql 数据库的 user 表中查看当前 root 用户的相关信息

```
select host, user, authentication_string, plugin from user;
```

查看表格中 root 用户的 host，默认应该显示的 localhost，只支持本地访问，不允许远程访问。

关闭MySQL root用户远程访问权限：

use mysql;

update user set host = "localhost" where user = "root" and host = "%";

flush privileges;

```
mysql> update user set host = "localhost" where user = "user1" and host = "%";
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.03 sec)

mysql>
```

打开MySQL root用户的远程访问权限：

use mysql;

update user set host = "%" where user = "root";

flush privileges;

```
mysql> update user set host = "%" where user = "user1";
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)
```

## 7、设置可信 IP 访问控制

通过数据库所在操作系统的防火墙限制，实现只有信任的 IP 才能通过监听器访问数据库。

```
mysql> GRANT ALL PRIVILEGES ON db.* TO 用户名@'IP子网/掩码';
```

## 8、连接数设置

根据您的机器性能和业务需求，设置最大、最小连接数。

在 MySQL 配置文件（my.conf 或 my.ini）的 \[mysqld] 配置段中添加`max_connections = 1000`，保存配置文件，重启 MySQL 服务后即可生效。
