第七章 安全与权限管理原创
# 第七章 安全与权限管理
数据库安全是整个系统安全的基石。本章将详细介绍 MySQL 8.0 的安全机制、账户管理最佳实践、权限系统以及相关的安全配置建议。
# 7.1 安全概述
MySQL 安全涉及多个层面:
- 网络安全:
- 防火墙:限制对 MySQL 端口(默认 3306, X Protocol 33060)的访问,仅允许必要的应用服务器或管理主机连接。
bind-address
: 在my.cnf
中设置,限制 MySQL 监听的网络接口。建议绑定到内网 IP,避免监听在公网地址。- 传输加密 (SSL/TLS): 对客户端和服务器之间的通信进行加密,防止数据在传输过程中被窃听。
- 操作系统安全:
- 运行 MySQL 的服务器应进行安全加固。
mysql
操作系统用户:使用专用、低权限的mysql
用户运行mysqld
进程。- 文件系统权限:严格控制 MySQL 数据目录、日志文件、配置文件的访问权限(如
datadir
权限设为 700)。
- MySQL 自身安全:
- 账户与权限管理:遵循最小权限原则。
- 密码策略:使用强密码,并启用密码复杂度验证。
- 审计:记录数据库的访问和操作行为。
- 安全相关配置参数。
# 7.2 账户管理最佳实践
# 7.2.1 命名规范
- 为不同应用或服务创建独立的 MySQL 用户。
- 用户名应具有一定描述性,避免使用通用或默认名称(如
test
,admin
)。
# 7.2.2 最小权限原则 (Principle of Least Privilege)
- 为每个用户授予其完成任务所必需的最小权限集。
- 避免授予
ALL PRIVILEGES
或过高的全局权限(如SUPER
,FILE
,PROCESS
),除非确实需要。 - 权限应尽可能限制在特定的数据库或表上。
# 7.2.3 密码策略
- 使用强密码: 密码应包含大小写字母、数字和特殊字符,长度足够(建议 12 位以上)。
- MySQL 8.0 默认认证插件:
caching_sha2_password
提供比旧版mysql_native_password
更高的安全性。确保客户端驱动支持此插件。 - 密码复杂度验证: 启用
validate_password
插件强制执行密码复杂度要求。-- 安装插件 (通常默认安装,需启用) -- INSTALL PLUGIN validate_password SONAME 'validate_password.so'; -- 在 my.cnf 中启用 -- [mysqld] -- plugin-load-add=validate_password.so -- validate-password=FORCE_PLUS_PERMANENT -- validate_password.policy=MEDIUM -- 或 STRONG -- validate_password.length=8 -- ... 其他策略参数 ...
1
2
3
4
5
6
7
8
9 - 密码过期策略: MySQL 8.0 支持设置密码过期时间。
-- 全局设置默认过期时间 -- SET PERSIST default_password_lifetime = 90; -- 90 天 -- 为特定用户设置 ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY; ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE NEVER; -- 永不过期 ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE DEFAULT; -- 使用全局设置
1
2
3
4
5
6 - 密码重用限制: 可以限制密码重用的次数和时间间隔。
-- SET PERSIST password_history = 5; -- SET PERSIST password_reuse_interval = 365; -- 天 ALTER USER 'app_user'@'localhost' PASSWORD HISTORY 5; ALTER USER 'app_user'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
1
2
3
4 - 定期更换密码: 即使设置了过期策略,也建议定期主动更换关键账户(如管理账户)的密码。
# 7.2.4 账户来源限制
- 创建用户时,明确指定允许连接的主机 (
'user'@'hostname'
),而不是使用通配符'%'
。CREATE USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'password'; CREATE USER 'report_user'@'10.0.0.%' IDENTIFIED BY 'password'; -- 允许某个网段
1
2
# 7.2.5 定期审计账户
- 定期审查
mysql.user
表,检查是否存在不再使用或权限过高的账户。SELECT user, host, account_locked, password_expired, password_last_changed FROM mysql.user;
1 - MySQL 8.0 引入了账户锁定功能:
ALTER USER 'old_user'@'localhost' ACCOUNT LOCK; ALTER USER 'user_to_enable'@'localhost' ACCOUNT UNLOCK;
1
2
# 7.2.6 移除匿名用户和 test 数据库
mysql_secure_installation
脚本会帮助完成此操作。- 手动检查并删除:
-- 查找匿名用户 (user 为空) SELECT user, host FROM mysql.user WHERE user = ''; DROP USER ''@'localhost'; -- 根据实际 host 删除 DROP USER ''@'%'; -- 删除 test 数据库 DROP DATABASE IF EXISTS test;
1
2
3
4
5
6
7
# 7.3 权限系统详解
# 7.3.1 授权 (GRANT)
GRANT privilege_type [(column_list)] [, privilege_type [(column_list)]] ...
ON privilege_level
TO user_specification [, user_specification] ...
[WITH GRANT OPTION];
-- privilege_type: 如 SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE, SUPER, FILE, PROCESS, RELOAD, SHUTDOWN, REPLICATION SLAVE, REPLICATION CLIENT, ALL PRIVILEGES 等。
-- privilege_level:
-- *.* -- 全局权限
-- db_name.* -- 数据库级别权限
-- db_name.tbl_name -- 表级别权限
-- db_name.routine_name -- 存储过程/函数权限
-- (column_list) ON db_name.tbl_name -- 列级别权限 (仅限 SELECT, INSERT, UPDATE)
-- user_specification: 'user_name'@'host_name'
-- WITH GRANT OPTION: 允许被授权用户将他拥有的权限再授予其他用户 (谨慎使用)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 7.1 复制专用账户权限设计
# 最小权限原则实现
-- 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPassword'
REQUIRE SSL;
-- 授予最小必要权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'repl'@'%';
-- 查看用户权限
SHOW GRANTS FOR 'repl'@'%';
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
安全建议
- 定期更改复制用户密码
- 限制复制用户的连接来源
- 避免使用root用户作为复制用户
- 启用密码复杂度策略
# 7.2 SSL加密通信配置
# 证书生成
# 生成CA证书
mysql_ssl_rsa_setup --uid=mysql
# 验证证书生成
ls -l /var/lib/mysql/*.pem
1
2
3
4
5
2
3
4
5
# 配置SSL加密
# my.cnf 主节点配置
[mysqld]
ssl_ca=/var/lib/mysql/ca.pem
ssl_cert=/var/lib/mysql/server-cert.pem
ssl_key=/var/lib/mysql/server-key.pem
require_secure_transport=ON
1
2
3
4
5
6
2
3
4
5
6
-- 从节点复制配置
CHANGE REPLICATION SOURCE TO
SOURCE_SSL=1,
SOURCE_SSL_CA='/var/lib/mysql/ca.pem',
SOURCE_SSL_CERT='/var/lib/mysql/client-cert.pem',
SOURCE_SSL_KEY='/var/lib/mysql/client-key.pem';
1
2
3
4
5
6
2
3
4
5
6
# 验证SSL状态
-- 查看SSL状态
SHOW GLOBAL VARIABLES LIKE '%ssl%';
-- 查看当前连接是否使用SSL
SHOW STATUS LIKE 'Ssl_cipher';
1
2
3
4
5
2
3
4
5
# 7.3 审计策略
# 启用审计插件
-- 安装审计插件
INSTALL PLUGIN audit_log SONAME 'audit_log.so';
-- 配置审计规则
SET GLOBAL audit_log_policy = 'ALL';
SET GLOBAL audit_log_format = 'JSON';
1
2
3
4
5
6
2
3
4
5
6
# 审计日志配置
# my.cnf
[mysqld]
audit_log_file = /var/log/mysql/audit.log
audit_log_rotate_on_size = 100M
audit_log_rotations = 10
1
2
3
4
5
2
3
4
5
# 敏感操作记录规范
操作类型 | 审计级别 | 记录内容 |
---|---|---|
DDL语句 | 高 | 完整SQL及执行结果 |
权限变更 | 高 | 用户、权限详情 |
数据修改 | 中 | 影响行数统计 |
复制操作 | 高 | 复制状态变更 |
审计日志分析
# 分析审计日志中的敏感操作
grep -i "grant\|revoke\|create user\|drop user" /var/log/mysql/audit.log
# 统计操作类型分布
jq -r '.event_class' /var/log/mysql/audit.log | sort | uniq -c
1
2
3
4
5
2
3
4
5
# 安全检查清单
- [ ] 定期更新密码策略
- [ ] 检查SSL证书有效期
- [ ] 审计日志轮转配置
- [ ] 敏感操作告警设置
- [ ] 权限定期审查
# 下一步
上次更新: 4/24/2025