数据库安全管理

1. 数据库安全概述

1.1 安全的重要性

数据库安全是系统架构中的核心环节,直接关系到数据的完整性、机密性和可用性。在讨论数据库安全时,我们需要考虑整个服务器主机安全(而不仅仅是MySQL服务),需要抵御攻击、窃听、扫描、破解等安全威胁。

安全威胁类型

  • 外部攻击:SQL注入、暴力破解、DDoS攻击
  • 内部威胁:权限滥用、误操作、数据泄露
  • 网络威胁:中间人攻击、数据窃听、未授权访问
  • 系统威胁:系统漏洞、配置错误、权限提升

1.2 MySQL安全机制

1. ACL访问控制

MySQL对所有连接数据库的用户进行了ACL(Access Control List)访问控制,减少服务器被内部不规范操作导致故障。

ACL特点

  • 细粒度权限控制
  • 用户级别权限管理
  • 数据库级别权限控制
  • 表级别权限控制
  • 列级别权限控制

2. SSL加密连接

MySQL支持客户端和服务器之间的SSL加密连接,保护数据传输安全。

SSL加密优势

  • 数据加密传输
  • 身份验证
  • 防止中间人攻击
  • 保护敏感信息

3. 密码安全

MySQL提供了多种密码安全机制:

  • 密码加密存储:使用加密算法存储密码
  • 密码策略:强制密码复杂度
  • 密码过期:定期更换密码
  • 密码验证插件:可扩展的密码验证机制

1.3 安全最佳实践

MySQL运行时,请遵循以下准则:

1. 不要给用户配置超级用户权限

1
2
3
4
5
-- 不推荐:给普通用户超级权限
GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'%' WITH GRANT OPTION;

-- 推荐:按需分配最小权限
GRANT SELECT, INSERT, UPDATE ON app_db.* TO 'app_user'@'%';

原则最小权限原则,只授予用户完成工作所需的最小权限。

2. 不要在数据库中存储明文密码

1
2
3
4
5
-- 不推荐:明文密码
CREATE USER 'user'@'localhost' IDENTIFIED BY 'plaintext_password';

-- 推荐:使用加密存储(MySQL自动处理)
CREATE USER 'user'@'localhost' IDENTIFIED BY 'encrypted_password';

说明:MySQL自动使用加密算法存储密码,但应用层也应避免存储明文密码。

3. 不要使用较为简单的字符密码

1
2
3
4
5
6
-- 不推荐:简单密码
CREATE USER 'user'@'localhost' IDENTIFIED BY '123456';
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';

-- 推荐:复杂密码
CREATE USER 'user'@'localhost' IDENTIFIED BY 'B@x123#Secure!2024';

密码复杂度要求

  • 至少8个字符
  • 包含大小写字母
  • 包含数字
  • 包含特殊字符
  • 避免常见密码

4. 不允许非授信任主机使用扫描

1
2
3
4
5
6
-- 不推荐:允许所有主机访问
GRANT ALL ON *.* TO 'user'@'%';

-- 推荐:限制特定主机或IP段
GRANT ALL ON *.* TO 'user'@'192.168.1.%';
GRANT ALL ON *.* TO 'user'@'10.0.0.10';

网络安全

  • 使用防火墙限制访问
  • 只允许必要的IP访问
  • 使用VPN或专用网络
  • 定期审查访问日志

1.4 安全架构层次

1
2
3
4
5
6
7
8
9
应用层安全

网络层安全(SSL/TLS)

MySQL服务层安全(ACL)

操作系统层安全

物理层安全

多层防护:安全不是单一层面的问题,需要多层防护。


2. 用户账户管理

2.1 登录和退出MySQL

本地连接

使用 mysql -u root -p 可以连接数据库,但这只是本地连接数据库的方式。

1
2
3
# 本地连接数据库
[root@sql ~]# mysql -uroot -p
Enter password:

远程连接

在生产环境中,很多情况下都是连接网络中某一个主机上的数据库。

连接参数

参数 说明 默认值
-P 指定连接远程数据库端口 3306
-h 指定连接远程数据库地址 localhost
-u 指定连接远程数据库账户 root
-p 指定连接远程数据库密码
-e 执行MySQL数据库SQL指令 -
-S 指定MySQL数据库Socket -

连接方式示例

1. 不安全的连接方式(不推荐)
1
2
# 密码直接写在命令行,会出现在命令历史中
[root@sql ~]# mysql -uroot -p'mypass'

安全风险

  • 密码出现在命令历史中
  • 可能被其他用户看到
  • 不符合安全规范
2. 推荐的安全连接方式
1
2
3
# 交互式输入密码
[root@sql ~]# mysql -uroot -p
Enter password:

优势

  • 密码不会出现在命令历史
  • 密码输入时不可见
  • 符合安全规范
3. 远程连接方式
1
2
3
# 连接远程数据库
[root@sql ~]# mysql -h192.168.56.11 -P3306 -uroot -p
Enter password:

说明

  • -h:指定远程主机IP
  • -P:指定端口(注意是大写P)
  • -u:指定用户名
  • -p:提示输入密码
4. 非交互式操作数据库
1
2
3
4
5
6
7
8
9
10
11
# 使用-e参数执行SQL命令
[root@sql ~]# mysql -uroot -pBgx123.com -e "show databases;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+

警告说明

  • MySQL会警告在命令行使用密码不安全
  • 建议使用交互式输入或配置文件

更安全的方式

1
2
3
4
5
6
7
8
# 使用配置文件
[root@sql ~]# mysql --defaults-file=/root/.my.cnf -e "show databases;"

# 配置文件内容
[client]
user=root
password=Bgx123.com
host=localhost

2.2 创建用户

MySQL提供了多种创建用户的方式。

方法一:CREATE USER语句创建

1
2
3
-- 先创建用户,后授权(推荐方式)
mysql> CREATE USER 'bgx1'@'localhost' IDENTIFIED BY 'BGX123.com';
Query OK, 0 rows affected (0.01 sec)

语法说明

  • CREATE USER:创建用户的关键字
  • 'bgx1'@'localhost':用户名@主机
  • IDENTIFIED BY:指定密码

注意:创建用户后需要单独授权。

方法二:基于已有用户进行授权

1
2
3
-- 如果用户已存在,直接授权
mysql> GRANT ALL ON *.* TO 'bgx4'@'localhost';
Query OK, 0 rows affected (0.00 sec)

方法三:使用GRANT语句创建用户并授权

1
2
3
-- 使用GRANT语句创建用户并授权(一步完成)
mysql> GRANT ALL ON *.* TO 'bgx2'@'localhost' IDENTIFIED BY 'BGX123.com';
Query OK, 0 rows affected (0.00 sec)

说明

  • 如果用户不存在,会自动创建
  • 如果用户已存在,只进行授权
  • 一步完成创建和授权

推荐方式

  • 生产环境:推荐使用方法一(CREATE USER + GRANT),步骤清晰
  • 开发环境:可以使用方法三(GRANT),快速创建

2.3 删除用户

MySQL提供了两种删除用户的方式。

方法一:DROP USER语句删除(推荐)

1
2
3
-- 删除用户(推荐方式)
mysql> DROP USER 'bgx1'@'localhost';
Query OK, 0 rows affected (0.00 sec)

**MySQL 5.7+**:可以直接删除,自动回收权限。

MySQL 5.6及以下:需要先回收权限,然后删除。

1
2
3
4
5
6
-- MySQL 5.6需要先回收权限
mysql> REVOKE ALL PRIVILEGES ON *.* FROM 'bgx1'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> DROP USER 'bgx1'@'localhost';
Query OK, 0 rows affected (0.00 sec)

方法二:DELETE语句删除(不推荐)

1
2
3
4
5
6
7
8
-- 使用DELETE语句删除(不推荐)
mysql> DELETE FROM mysql.user
-> WHERE user='bgx1' AND host='localhost';
Query OK, 1 row affected (0.00 sec)

-- 必须刷新权限
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

不推荐原因

  • 需要手动刷新权限
  • 可能遗漏相关权限表
  • 容易出错

推荐:使用 DROP USER 语句。

2.4 修改root用户密码

方法一:Shell修改方式(推荐)

1
2
3
4
# 使用mysqladmin修改密码
# mysqladmin -uroot -p'old_password' password 'new_password'

[root@sql ~]# mysqladmin -uroot -p'old_password' password 'new_password'

说明

  • 需要知道旧密码
  • 适合root用户修改自己的密码
  • 不需要登录MySQL

方法二:修改数据表

1
2
3
4
5
6
7
8
9
-- 登录MySQL后修改
mysql> UPDATE mysql.user SET
-> authentication_string=PASSWORD('new_password')
-> WHERE user='root' AND host='localhost';
Query OK, 1 row affected (0.00 sec)

-- 刷新权限(必须执行)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

注意

  • MySQL 5.7+ 使用 authentication_string 字段
  • MySQL 5.6 使用 password 字段
  • 必须执行 FLUSH PRIVILEGES

方法三:SET PASSWORD语句

1
2
3
-- 使用SET PASSWORD修改密码
mysql> SET PASSWORD=PASSWORD('new_password');
Query OK, 0 rows affected (0.00 sec)

说明

  • 修改当前登录用户的密码
  • 不需要刷新权限
  • 语法简洁

MySQL 8.0+语法

1
2
-- MySQL 8.0+ 使用新的语法
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

2.5 修改其他用户密码

方法一:SET PASSWORD FOR语句

1
2
3
4
5
6
7
-- 创建用户
mysql> CREATE USER 'bgx1'@'localhost' IDENTIFIED BY 'Bgx123.com';
Query OK, 0 rows affected (0.00 sec)

-- 修改用户密码
mysql> SET PASSWORD FOR 'bgx1'@'localhost'=PASSWORD('new_password');
Query OK, 0 rows affected (0.00 sec)

MySQL 8.0+语法

1
mysql> ALTER USER 'bgx1'@'localhost' IDENTIFIED BY 'new_password';

方法二:修改数据表

1
2
3
4
5
6
7
8
9
-- 修改数据表
mysql> UPDATE mysql.user SET
-> authentication_string=PASSWORD('new_password')
-> WHERE user='bgx1' AND host='localhost';
Query OK, 1 row affected (0.00 sec)

-- 刷新权限
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

普通用户自己修改密码

1
2
3
-- 普通用户登录后修改自己的密码
mysql> SET PASSWORD=PASSWORD("new_password");
Query OK, 0 rows affected (0.00 sec)

说明

  • 用户只能修改自己的密码
  • 需要知道旧密码(如果设置了)
  • 不需要特殊权限

3. 访问权限系统

3.1 MySQL权限表

MySQL使用多个权限表来管理用户权限,权限应用的顺序是:user → db → tables_priv → columns_priv

1. mysql.user(全局授权)

存储全局级别的用户权限和账户信息。

主要字段

字段类型 说明 示例
用户字段 用户标识 user, host
权限字段 全局权限 Select_priv, Insert_priv, Update_priv等
安全字段 安全相关 password, ssl_type, ssl_cipher等
资源控制字段 资源限制 max_connections, max_questions等

权限级别:全局级别(*.*

2. mysql.db(数据库级)

存储数据库级别的权限。

主要字段

  • 用户字段:user, host, db
  • 权限字段:Select_priv, Insert_priv等

权限级别:数据库级别(database.*

3. mysql.tables_priv(表级)

存储表级别的权限。

主要字段

  • 用户字段:user, host, db
  • 表字段:table_name
  • 权限字段:Table_priv, Column_priv

权限级别:表级别(database.table

4. mysql.columns_priv(列级)

存储列级别的权限。

主要字段

  • 用户字段:user, host, db
  • 表字段:table_name
  • 列字段:column_name
  • 权限字段:Column_priv

权限级别:列级别(database.table.column

3.2 权限应用顺序

MySQL按照以下顺序检查权限:

1
2
3
4
5
6
7
1. mysql.user(全局权限)

2. mysql.db(数据库权限)

3. mysql.tables_priv(表权限)

4. mysql.columns_priv(列权限)

权限匹配规则

  • 从全局到具体,逐级检查
  • 找到匹配的权限后停止检查
  • 如果所有级别都没有权限,拒绝访问

3.3 GRANT授权语法

基本语法格式

1
2
3
4
GRANT 权限列表 ON 库名.表名 
TO '用户名'@'客户端主机'
[IDENTIFIED BY '密码']
[WITH option 参数];

语法参数说明

1. 权限列表

所有权限

1
2
-- 所有权限(不包括授权权限)
GRANT ALL ON *.* TO 'user'@'localhost';

单独权限

1
2
-- 单独授权
GRANT SELECT, UPDATE, INSERT, DELETE ON *.* TO 'user'@'localhost';

常用权限

权限 说明
SELECT 查询权限
INSERT 插入权限
UPDATE 更新权限
DELETE 删除权限
CREATE 创建表权限
DROP 删除表权限
ALTER 修改表权限
INDEX 索引权限
ALL 所有权限(不包括GRANT)
2. 库名.表名

全局级别(Global level):

1
2
-- 所有库下的所有表
GRANT ALL ON *.* TO 'user'@'localhost';

数据库级别(Database level):

1
2
-- 针对bgx库下的所有表
GRANT ALL ON bgx.* TO 'user'@'localhost';

表级别(Table level):

1
2
-- 针对bgx库下的student表
GRANT ALL ON bgx.student TO 'user'@'localhost';

列级别(Column level):

1
2
-- 针对bgx库下t1表的特定字段
GRANT SELECT(id), INSERT(name,age) ON bgx.t1 TO 'user'@'localhost';
3. 客户端主机

指定本机

1
GRANT ALL ON *.* TO 'user'@'localhost';

指定具体主机

1
GRANT ALL ON *.* TO 'user'@'192.168.56.11';

指定网段

1
2
3
4
5
-- 192.168.56.0网段的所有主机
GRANT ALL ON *.* TO 'user'@'192.168.56.%';

-- 192.168.2.0网段的所有主机
GRANT ALL ON *.* TO 'user'@'192.168.2.%';

所有主机(不推荐):

1
2
-- 允许所有主机访问(安全风险)
GRANT ALL ON *.* TO 'user'@'%';

主机名

1
2
-- 使用主机名
GRANT ALL ON *.* TO 'user'@'server.example.com';
4. WITH参数

GRANT OPTION(授权选项)

1
2
-- 允许用户将自己的权限授予其他用户
GRANT ALL ON *.* TO 'user'@'localhost' WITH GRANT OPTION;

资源限制参数

参数 说明
MAX_QUERIES_PER_HOUR 每小时允许执行的查询数
MAX_UPDATES_PER_HOUR 每小时允许执行的更新数
MAX_CONNECTIONS_PER_HOUR 每小时可以建立的连接数
MAX_USER_CONNECTIONS 单个用户同时可以建立的连接数

示例

1
2
3
4
5
6
7
-- 限制每小时最多1000次查询
GRANT ALL ON *.* TO 'user'@'localhost'
WITH MAX_QUERIES_PER_HOUR 1000;

-- 限制同时最多10个连接
GRANT ALL ON *.* TO 'user'@'localhost'
WITH MAX_USER_CONNECTIONS 10;

3.4 GRANT授权示例

示例1:全局权限

1
2
-- 授予所有数据库的所有权限
GRANT ALL ON *.* TO 'admin1'@'%' IDENTIFIED BY 'Bgx123.com';

说明

  • 权限范围:所有数据库的所有表
  • 主机范围:所有主机(%
  • 权限:所有权限

示例2:带GRANT OPTION的全局权限

1
2
3
4
-- 授予所有权限,并允许授权给其他用户
GRANT ALL ON *.* TO 'admin2'@'%'
IDENTIFIED BY 'Bgx123.com'
WITH GRANT OPTION;

说明

  • 拥有所有权限
  • 可以将权限授予其他用户
  • 通常用于管理员账户

示例3:数据库级别权限

1
2
-- 授予bbs数据库的所有权限
GRANT ALL ON bbs.* TO 'admin3'@'%' IDENTIFIED BY 'Bgx123.com';

说明

  • 权限范围:bbs数据库的所有表
  • 不能访问其他数据库

示例4:限制IP的数据库权限

1
2
3
-- 只允许特定IP访问bbs数据库
GRANT ALL ON bbs.* TO 'admin3'@'192.168.70.160'
IDENTIFIED BY 'Bgx123.com';

说明

  • 权限范围:bbs数据库
  • 主机限制:只允许192.168.70.160访问
  • 提高安全性

示例5:表级别权限

1
2
-- 授予bbs.user表的所有权限
GRANT ALL ON bbs.user TO 'admin4'@'%' IDENTIFIED BY 'Bgx123.com';

说明

  • 权限范围:bbs数据库的user表
  • 不能访问bbs数据库的其他表

示例6:列级别权限

1
2
3
-- 授予bbs.user表的特定列权限
GRANT SELECT(id), INSERT(name,age) ON bbs.user
TO 'admin5'@'%' IDENTIFIED BY 'Bgx123.com';

说明

  • 只能查询id列
  • 只能插入name和age列
  • 最细粒度的权限控制

3.5 权限设计最佳实践

1. 最小权限原则

1
2
3
4
5
-- 不推荐:授予过多权限
GRANT ALL ON *.* TO 'app_user'@'%';

-- 推荐:只授予必要的权限
GRANT SELECT, INSERT, UPDATE ON app_db.* TO 'app_user'@'%';

2. 按角色分配权限

1
2
3
4
5
6
7
8
-- 只读用户
GRANT SELECT ON database.* TO 'readonly_user'@'%';

-- 读写用户
GRANT SELECT, INSERT, UPDATE ON database.* TO 'readwrite_user'@'%';

-- 管理员用户
GRANT ALL ON database.* TO 'admin_user'@'localhost';

3. 限制主机访问

1
2
3
4
5
6
-- 不推荐:允许所有主机
GRANT ALL ON *.* TO 'user'@'%';

-- 推荐:限制特定IP或网段
GRANT ALL ON *.* TO 'user'@'192.168.1.%';
GRANT ALL ON *.* TO 'user'@'10.0.0.10';

4. 使用资源限制

1
2
3
4
5
6
-- 限制资源使用
GRANT ALL ON database.* TO 'user'@'%'
WITH
MAX_QUERIES_PER_HOUR 1000,
MAX_CONNECTIONS_PER_HOUR 100,
MAX_USER_CONNECTIONS 10;

4. 访问权限回收

4.1 查看用户权限

查看当前用户权限

1
2
3
4
5
6
7
8
9
-- 查看当前登录用户的权限
mysql> SHOW GRANTS;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

输出说明

  • 显示当前用户的所有权限
  • 包括全局权限和特殊权限

查看其他用户权限

1
2
3
4
5
6
7
8
-- 查看指定用户的权限
mysql> SHOW GRANTS FOR 'bgx2'@'localhost';
+---------------------------------------------------+
| Grants for bgx2@localhost |
+---------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'bgx2'@'localhost' |
+---------------------------------------------------+
1 row in set (0.00 sec)

语法

1
SHOW GRANTS [FOR 'user'@'host'];

使用格式化输出

1
2
3
4
5
-- 使用\G格式化输出
mysql> SHOW GRANTS FOR 'bgx2'@'localhost'\G
*************************** 1. row ***************************
Grants for bgx2@localhost: GRANT ALL PRIVILEGES ON *.* TO 'bgx2'@'localhost'
1 row in set (0.00 sec)

4.2 回收权限

REVOKE语法

1
REVOKE 权限列表 ON 数据库名.表名 FROM 用户名@'客户端主机';

回收特定权限

1
2
3
4
5
6
7
8
9
10
11
12
-- 回收DELETE权限
mysql> REVOKE DELETE ON *.* FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

-- 验证权限回收
mysql> SHOW GRANTS FOR 'bgx2'@'localhost';
+------------------------------------------------------------------+
| Grants for bgx2@localhost |
+------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, CREATE, DROP, ... ON *.* TO 'bgx2'@'localhost' |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

说明

  • 只回收指定的权限
  • 其他权限保持不变
  • 需要刷新权限(某些情况下)

回收所有权限

1
2
3
4
5
6
7
8
9
10
11
12
-- 回收所有权限
mysql> REVOKE ALL PRIVILEGES ON *.* FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

-- 验证
mysql> SHOW GRANTS FOR 'bgx2'@'localhost';
+--------------------------------------+
| Grants for bgx2@localhost |
+--------------------------------------+
| GRANT USAGE ON *.* TO 'bgx2'@'localhost' |
+--------------------------------------+
1 row in set (0.00 sec)

说明

  • USAGE权限表示只有连接权限,没有其他权限
  • 用户仍然可以连接,但无法执行任何操作

回收GRANT权限

1
2
3
-- 回收GRANT OPTION权限
mysql> REVOKE GRANT OPTION ON *.* FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

说明

  • 回收用户的授权权限
  • 用户不能再将权限授予其他用户
  • 但用户的其他权限不受影响

回收数据库级别权限

1
2
3
-- 回收特定数据库的权限
mysql> REVOKE ALL ON bbs.* FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

回收表级别权限

1
2
3
-- 回收特定表的权限
mysql> REVOKE ALL ON bbs.user FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

回收列级别权限

1
2
3
4
-- 回收特定列的权限
mysql> REVOKE SELECT(id), INSERT(name,age) ON bbs.user
-> FROM 'bgx2'@'localhost';
Query OK, 0 rows affected (0.00 sec)

4.3 权限回收注意事项

1. 权限回收的级联性

1
2
3
4
-- 回收全局权限不会自动回收数据库权限
-- 需要分别回收
REVOKE ALL ON *.* FROM 'user'@'localhost';
REVOKE ALL ON database.* FROM 'user'@'localhost';

2. 刷新权限

1
2
-- 某些情况下需要刷新权限
FLUSH PRIVILEGES;

何时需要刷新

  • 直接修改权限表后
  • 不确定权限是否生效时
  • 权限回收后立即生效(通常不需要)

3. 检查权限影响

1
2
3
4
5
-- 回收权限前,先查看用户权限
SHOW GRANTS FOR 'user'@'host';

-- 回收权限后,再次查看确认
SHOW GRANTS FOR 'user'@'host';

4. 批量权限回收

1
2
3
4
5
-- 回收多个权限
REVOKE SELECT, INSERT, UPDATE ON *.* FROM 'user'@'localhost';

-- 或使用ALL回收所有权限
REVOKE ALL PRIVILEGES ON *.* FROM 'user'@'localhost';

5. 权限管理最佳实践

5.1 用户权限设计原则

1. 最小权限原则

1
2
3
4
5
6
7
8
9
-- 只授予完成工作所需的最小权限
-- 应用用户:只读或读写特定数据库
GRANT SELECT, INSERT, UPDATE ON app_db.* TO 'app_user'@'%';

-- 备份用户:只读权限
GRANT SELECT ON *.* TO 'backup_user'@'localhost';

-- 监控用户:只读系统表
GRANT SELECT ON performance_schema.* TO 'monitor_user'@'localhost';

2. 角色分离

1
2
3
4
5
6
7
8
9
10
11
12
-- 不同角色使用不同账户
-- 管理员账户
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;

-- 应用账户
CREATE USER 'app'@'%' IDENTIFIED BY 'app_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app'@'%';

-- 只读账户
CREATE USER 'readonly'@'%' IDENTIFIED BY 'readonly_password';
GRANT SELECT ON app_db.* TO 'readonly'@'%';

3. 定期审查权限

1
2
3
4
5
6
7
8
9
10
-- 定期检查用户权限
SELECT user, host, db, table_name, table_priv
FROM mysql.tables_priv
ORDER BY user, host;

-- 检查是否有过多权限的用户
SELECT user, host
FROM mysql.user
WHERE Super_priv = 'Y'
AND user != 'root';

5.2 安全配置建议

1. 密码策略

1
2
3
4
5
6
7
-- 使用复杂密码
CREATE USER 'user'@'localhost'
IDENTIFIED BY 'Complex@Password123!';

-- 定期更换密码
ALTER USER 'user'@'localhost'
IDENTIFIED BY 'NewComplex@Password456!';

2. 主机限制

1
2
3
4
5
6
7
8
9
-- 限制访问主机
-- 不推荐
GRANT ALL ON *.* TO 'user'@'%';

-- 推荐:限制IP段
GRANT ALL ON *.* TO 'user'@'192.168.1.%';

-- 推荐:限制特定IP
GRANT ALL ON *.* TO 'user'@'10.0.0.10';

3. 资源限制

1
2
3
4
5
6
7
-- 设置资源限制
GRANT ALL ON database.* TO 'user'@'%'
WITH
MAX_QUERIES_PER_HOUR 1000,
MAX_UPDATES_PER_HOUR 500,
MAX_CONNECTIONS_PER_HOUR 100,
MAX_USER_CONNECTIONS 10;

5.3 权限审计

1. 记录权限变更

1
2
3
4
5
6
7
8
9
10
-- 创建权限审计表
CREATE TABLE permission_audit (
id INT AUTO_INCREMENT PRIMARY KEY,
user_name VARCHAR(50),
host VARCHAR(50),
action VARCHAR(20),
permission TEXT,
changed_by VARCHAR(50),
change_time DATETIME DEFAULT NOW()
);

2. 定期检查

1
2
3
4
5
6
7
8
9
-- 检查所有用户权限
SELECT user, host,
CASE
WHEN Super_priv = 'Y' THEN 'Super'
WHEN Grant_priv = 'Y' THEN 'Grant'
ELSE 'Normal'
END AS privilege_level
FROM mysql.user
ORDER BY user, host;

6. 安全加固检查清单

6.1 用户账户安全

  • 所有用户使用强密码
  • 定期更换密码
  • 删除不必要的用户账户
  • 限制root用户远程登录
  • 为不同应用创建独立用户

6.2 权限配置安全

  • 遵循最小权限原则
  • 限制主机访问范围
  • 避免使用%通配符
  • 定期审查用户权限
  • 回收不必要的权限

6.3 网络安全

  • 使用SSL加密连接
  • 配置防火墙规则
  • 限制数据库端口访问
  • 使用VPN或专用网络
  • 定期检查访问日志

6.4 系统安全

  • 及时更新MySQL版本
  • 配置安全参数
  • 启用审计日志
  • 定期备份数据
  • 监控异常访问

7. 总结

7.1 安全管理的核心价值

  1. 数据保护:保护数据不被未授权访问
  2. 权限控制:精确控制用户访问权限
  3. 审计追踪:记录用户操作,便于审计
  4. 合规要求:满足法律法规要求

7.2 安全管理原则

  1. 最小权限原则:只授予必要的权限
  2. 角色分离:不同角色使用不同账户
  3. 定期审查:定期检查和调整权限
  4. 多层防护:从网络到应用的多层安全

7.3 架构师建议

  1. 安全优先:安全是系统设计的第一要务
  2. 权限最小化:默认拒绝,按需授权
  3. 定期审计:建立权限审计机制
  4. 文档维护:记录所有权限配置和变更
  5. 应急响应:建立安全事件响应机制

7.4 安全检查清单

  • 所有用户使用强密码
  • 遵循最小权限原则
  • 限制主机访问范围
  • 定期审查用户权限
  • 启用SSL加密
  • 配置防火墙规则
  • 建立审计日志
  • 定期安全评估

相关文章