Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL8-SOP

    • 第一章 概述
    • 第二章 环境准备
    • 第三章 安装部署规范
    • 第四章 ReplicaSet高可用配置
    • 第五章 监控与日常维护
    • 第六章 故障处理手册
    • 第七章 安全与权限管理
      • 7.1 安全概述
      • 7.2 账户管理最佳实践
        • 7.2.1 命名规范
        • 7.2.2 最小权限原则 (Principle of Least Privilege)
        • 7.2.3 密码策略
        • 7.2.4 账户来源限制
        • 7.2.5 定期审计账户
        • 7.2.6 移除匿名用户和 test 数据库
      • 7.3 权限系统详解
        • 7.3.1 授权 (GRANT)
      • 7.1 复制专用账户权限设计
        • 最小权限原则实现
      • 7.2 SSL加密通信配置
        • 证书生成
        • 配置SSL加密
        • 验证SSL状态
      • 7.3 审计策略
        • 启用审计插件
        • 审计日志配置
        • 敏感操作记录规范
        • 安全检查清单
      • 下一步
    • 第八章 扩展与升级方案
    • 附录
  • 专题系列
  • MySQL8-SOP
Carry の Blog
2024-01-09
目录

第七章 安全与权限管理原创

# 第七章 安全与权限管理

数据库安全是整个系统安全的基石。本章将详细介绍 MySQL 8.0 的安全机制、账户管理最佳实践、权限系统以及相关的安全配置建议。

# 7.1 安全概述

MySQL 安全涉及多个层面:

  1. 网络安全:
    • 防火墙:限制对 MySQL 端口(默认 3306, X Protocol 33060)的访问,仅允许必要的应用服务器或管理主机连接。
    • bind-address: 在 my.cnf 中设置,限制 MySQL 监听的网络接口。建议绑定到内网 IP,避免监听在公网地址。
    • 传输加密 (SSL/TLS): 对客户端和服务器之间的通信进行加密,防止数据在传输过程中被窃听。
  2. 操作系统安全:
    • 运行 MySQL 的服务器应进行安全加固。
    • mysql 操作系统用户:使用专用、低权限的 mysql 用户运行 mysqld 进程。
    • 文件系统权限:严格控制 MySQL 数据目录、日志文件、配置文件的访问权限(如 datadir 权限设为 700)。
  3. 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

# 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

安全建议

  1. 定期更改复制用户密码
  2. 限制复制用户的连接来源
  3. 避免使用root用户作为复制用户
  4. 启用密码复杂度策略

# 7.2 SSL加密通信配置

# 证书生成

# 生成CA证书
mysql_ssl_rsa_setup --uid=mysql

# 验证证书生成
ls -l /var/lib/mysql/*.pem
1
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
-- 从节点复制配置
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

# 验证SSL状态

-- 查看SSL状态
SHOW GLOBAL VARIABLES LIKE '%ssl%';

-- 查看当前连接是否使用SSL
SHOW STATUS LIKE 'Ssl_cipher';
1
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

# 审计日志配置

# 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

# 敏感操作记录规范

操作类型 审计级别 记录内容
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

# 安全检查清单

  • [ ] 定期更新密码策略
  • [ ] 检查SSL证书有效期
  • [ ] 审计日志轮转配置
  • [ ] 敏感操作告警设置
  • [ ] 权限定期审查

# 下一步

  • 扩展与升级方案
  • 附录
#MySQL#数据库#安全
上次更新: 4/24/2025

← 第六章 故障处理手册 第八章 扩展与升级方案→

最近更新
01
tidb fast ddl
04-04
02
TiDB配置文件调优 原创
04-03
03
如何移除TiDB中的表分区 原创
04-03
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式