第431集数据库安全管理
数据库安全管理
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. 不要在数据库中存储明文密码
1 | -- 不推荐:明文密码 |
说明:MySQL自动使用加密算法存储密码,但应用层也应避免存储明文密码。
3. 不要使用较为简单的字符密码
1 | -- 不推荐:简单密码 |
密码复杂度要求:
- 至少8个字符
- 包含大小写字母
- 包含数字
- 包含特殊字符
- 避免常见密码
4. 不允许非授信任主机使用扫描
1 | -- 不推荐:允许所有主机访问 |
网络安全:
- 使用防火墙限制访问
- 只允许必要的IP访问
- 使用VPN或专用网络
- 定期审查访问日志
1.4 安全架构层次
1 | 应用层安全 |
多层防护:安全不是单一层面的问题,需要多层防护。
2. 用户账户管理
2.1 登录和退出MySQL
本地连接
使用 mysql -u root -p 可以连接数据库,但这只是本地连接数据库的方式。
1 | # 本地连接数据库 |
远程连接
在生产环境中,很多情况下都是连接网络中某一个主机上的数据库。
连接参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
-P |
指定连接远程数据库端口 | 3306 |
-h |
指定连接远程数据库地址 | localhost |
-u |
指定连接远程数据库账户 | root |
-p |
指定连接远程数据库密码 | 空 |
-e |
执行MySQL数据库SQL指令 | - |
-S |
指定MySQL数据库Socket | - |
连接方式示例
1. 不安全的连接方式(不推荐)
1 | # 密码直接写在命令行,会出现在命令历史中 |
安全风险:
- 密码出现在命令历史中
- 可能被其他用户看到
- 不符合安全规范
2. 推荐的安全连接方式
1 | # 交互式输入密码 |
优势:
- 密码不会出现在命令历史
- 密码输入时不可见
- 符合安全规范
3. 远程连接方式
1 | # 连接远程数据库 |
说明:
-h:指定远程主机IP-P:指定端口(注意是大写P)-u:指定用户名-p:提示输入密码
4. 非交互式操作数据库
1 | # 使用-e参数执行SQL命令 |
警告说明:
- MySQL会警告在命令行使用密码不安全
- 建议使用交互式输入或配置文件
更安全的方式:
1 | # 使用配置文件 |
2.2 创建用户
MySQL提供了多种创建用户的方式。
方法一:CREATE USER语句创建
1 | -- 先创建用户,后授权(推荐方式) |
语法说明:
CREATE USER:创建用户的关键字'bgx1'@'localhost':用户名@主机IDENTIFIED BY:指定密码
注意:创建用户后需要单独授权。
方法二:基于已有用户进行授权
1 | -- 如果用户已存在,直接授权 |
方法三:使用GRANT语句创建用户并授权
1 | -- 使用GRANT语句创建用户并授权(一步完成) |
说明:
- 如果用户不存在,会自动创建
- 如果用户已存在,只进行授权
- 一步完成创建和授权
推荐方式:
- 生产环境:推荐使用方法一(CREATE USER + GRANT),步骤清晰
- 开发环境:可以使用方法三(GRANT),快速创建
2.3 删除用户
MySQL提供了两种删除用户的方式。
方法一:DROP USER语句删除(推荐)
1 | -- 删除用户(推荐方式) |
**MySQL 5.7+**:可以直接删除,自动回收权限。
MySQL 5.6及以下:需要先回收权限,然后删除。
1 | -- MySQL 5.6需要先回收权限 |
方法二:DELETE语句删除(不推荐)
1 | -- 使用DELETE语句删除(不推荐) |
不推荐原因:
- 需要手动刷新权限
- 可能遗漏相关权限表
- 容易出错
推荐:使用 DROP USER 语句。
2.4 修改root用户密码
方法一:Shell修改方式(推荐)
1 | # 使用mysqladmin修改密码 |
说明:
- 需要知道旧密码
- 适合root用户修改自己的密码
- 不需要登录MySQL
方法二:修改数据表
1 | -- 登录MySQL后修改 |
注意:
- MySQL 5.7+ 使用
authentication_string字段 - MySQL 5.6 使用
password字段 - 必须执行
FLUSH PRIVILEGES
方法三:SET PASSWORD语句
1 | -- 使用SET PASSWORD修改密码 |
说明:
- 修改当前登录用户的密码
- 不需要刷新权限
- 语法简洁
MySQL 8.0+语法:
1 | -- MySQL 8.0+ 使用新的语法 |
2.5 修改其他用户密码
方法一:SET PASSWORD FOR语句
1 | -- 创建用户 |
MySQL 8.0+语法:
1 | mysql> ALTER USER 'bgx1'@'localhost' IDENTIFIED BY 'new_password'; |
方法二:修改数据表
1 | -- 修改数据表 |
普通用户自己修改密码
1 | -- 普通用户登录后修改自己的密码 |
说明:
- 用户只能修改自己的密码
- 需要知道旧密码(如果设置了)
- 不需要特殊权限
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 | 1. mysql.user(全局权限) |
权限匹配规则:
- 从全局到具体,逐级检查
- 找到匹配的权限后停止检查
- 如果所有级别都没有权限,拒绝访问
3.3 GRANT授权语法
基本语法格式
1 | GRANT 权限列表 ON 库名.表名 |
语法参数说明
1. 权限列表
所有权限:
1 | -- 所有权限(不包括授权权限) |
单独权限:
1 | -- 单独授权 |
常用权限:
| 权限 | 说明 |
|---|---|
SELECT |
查询权限 |
INSERT |
插入权限 |
UPDATE |
更新权限 |
DELETE |
删除权限 |
CREATE |
创建表权限 |
DROP |
删除表权限 |
ALTER |
修改表权限 |
INDEX |
索引权限 |
ALL |
所有权限(不包括GRANT) |
2. 库名.表名
全局级别(Global level):
1 | -- 所有库下的所有表 |
数据库级别(Database level):
1 | -- 针对bgx库下的所有表 |
表级别(Table level):
1 | -- 针对bgx库下的student表 |
列级别(Column level):
1 | -- 针对bgx库下t1表的特定字段 |
3. 客户端主机
指定本机:
1 | GRANT ALL ON *.* TO 'user'@'localhost'; |
指定具体主机:
1 | GRANT ALL ON *.* TO 'user'@'192.168.56.11'; |
指定网段:
1 | -- 192.168.56.0网段的所有主机 |
所有主机(不推荐):
1 | -- 允许所有主机访问(安全风险) |
主机名:
1 | -- 使用主机名 |
4. WITH参数
GRANT OPTION(授权选项):
1 | -- 允许用户将自己的权限授予其他用户 |
资源限制参数:
| 参数 | 说明 |
|---|---|
MAX_QUERIES_PER_HOUR |
每小时允许执行的查询数 |
MAX_UPDATES_PER_HOUR |
每小时允许执行的更新数 |
MAX_CONNECTIONS_PER_HOUR |
每小时可以建立的连接数 |
MAX_USER_CONNECTIONS |
单个用户同时可以建立的连接数 |
示例:
1 | -- 限制每小时最多1000次查询 |
3.4 GRANT授权示例
示例1:全局权限
1 | -- 授予所有数据库的所有权限 |
说明:
- 权限范围:所有数据库的所有表
- 主机范围:所有主机(
%) - 权限:所有权限
示例2:带GRANT OPTION的全局权限
1 | -- 授予所有权限,并允许授权给其他用户 |
说明:
- 拥有所有权限
- 可以将权限授予其他用户
- 通常用于管理员账户
示例3:数据库级别权限
1 | -- 授予bbs数据库的所有权限 |
说明:
- 权限范围:bbs数据库的所有表
- 不能访问其他数据库
示例4:限制IP的数据库权限
1 | -- 只允许特定IP访问bbs数据库 |
说明:
- 权限范围:bbs数据库
- 主机限制:只允许192.168.70.160访问
- 提高安全性
示例5:表级别权限
1 | -- 授予bbs.user表的所有权限 |
说明:
- 权限范围:bbs数据库的user表
- 不能访问bbs数据库的其他表
示例6:列级别权限
1 | -- 授予bbs.user表的特定列权限 |
说明:
- 只能查询id列
- 只能插入name和age列
- 最细粒度的权限控制
3.5 权限设计最佳实践
1. 最小权限原则
1 | -- 不推荐:授予过多权限 |
2. 按角色分配权限
1 | -- 只读用户 |
3. 限制主机访问
1 | -- 不推荐:允许所有主机 |
4. 使用资源限制
1 | -- 限制资源使用 |
4. 访问权限回收
4.1 查看用户权限
查看当前用户权限
1 | -- 查看当前登录用户的权限 |
输出说明:
- 显示当前用户的所有权限
- 包括全局权限和特殊权限
查看其他用户权限
1 | -- 查看指定用户的权限 |
语法:
1 | SHOW GRANTS [FOR 'user'@'host']; |
使用格式化输出
1 | -- 使用\G格式化输出 |
4.2 回收权限
REVOKE语法
1 | REVOKE 权限列表 ON 数据库名.表名 FROM 用户名@'客户端主机'; |
回收特定权限
1 | -- 回收DELETE权限 |
说明:
- 只回收指定的权限
- 其他权限保持不变
- 需要刷新权限(某些情况下)
回收所有权限
1 | -- 回收所有权限 |
说明:
USAGE权限表示只有连接权限,没有其他权限- 用户仍然可以连接,但无法执行任何操作
回收GRANT权限
1 | -- 回收GRANT OPTION权限 |
说明:
- 回收用户的授权权限
- 用户不能再将权限授予其他用户
- 但用户的其他权限不受影响
回收数据库级别权限
1 | -- 回收特定数据库的权限 |
回收表级别权限
1 | -- 回收特定表的权限 |
回收列级别权限
1 | -- 回收特定列的权限 |
4.3 权限回收注意事项
1. 权限回收的级联性
1 | -- 回收全局权限不会自动回收数据库权限 |
2. 刷新权限
1 | -- 某些情况下需要刷新权限 |
何时需要刷新:
- 直接修改权限表后
- 不确定权限是否生效时
- 权限回收后立即生效(通常不需要)
3. 检查权限影响
1 | -- 回收权限前,先查看用户权限 |
4. 批量权限回收
1 | -- 回收多个权限 |
5. 权限管理最佳实践
5.1 用户权限设计原则
1. 最小权限原则
1 | -- 只授予完成工作所需的最小权限 |
2. 角色分离
1 | -- 不同角色使用不同账户 |
3. 定期审查权限
1 | -- 定期检查用户权限 |
5.2 安全配置建议
1. 密码策略
1 | -- 使用复杂密码 |
2. 主机限制
1 | -- 限制访问主机 |
3. 资源限制
1 | -- 设置资源限制 |
5.3 权限审计
1. 记录权限变更
1 | -- 创建权限审计表 |
2. 定期检查
1 | -- 检查所有用户权限 |
6. 安全加固检查清单
6.1 用户账户安全
- 所有用户使用强密码
- 定期更换密码
- 删除不必要的用户账户
- 限制root用户远程登录
- 为不同应用创建独立用户
6.2 权限配置安全
- 遵循最小权限原则
- 限制主机访问范围
- 避免使用
%通配符 - 定期审查用户权限
- 回收不必要的权限
6.3 网络安全
- 使用SSL加密连接
- 配置防火墙规则
- 限制数据库端口访问
- 使用VPN或专用网络
- 定期检查访问日志
6.4 系统安全
- 及时更新MySQL版本
- 配置安全参数
- 启用审计日志
- 定期备份数据
- 监控异常访问
7. 总结
7.1 安全管理的核心价值
- 数据保护:保护数据不被未授权访问
- 权限控制:精确控制用户访问权限
- 审计追踪:记录用户操作,便于审计
- 合规要求:满足法律法规要求
7.2 安全管理原则
- 最小权限原则:只授予必要的权限
- 角色分离:不同角色使用不同账户
- 定期审查:定期检查和调整权限
- 多层防护:从网络到应用的多层安全
7.3 架构师建议
- 安全优先:安全是系统设计的第一要务
- 权限最小化:默认拒绝,按需授权
- 定期审计:建立权限审计机制
- 文档维护:记录所有权限配置和变更
- 应急响应:建立安全事件响应机制
7.4 安全检查清单
- 所有用户使用强密码
- 遵循最小权限原则
- 限制主机访问范围
- 定期审查用户权限
- 启用SSL加密
- 配置防火墙规则
- 建立审计日志
- 定期安全评估
相关文章:


