MySQL如何限制账号权限,最小权限原则实践

前言

数据库安全最重要的一条准则就是最小权限原则 :一个业务账号只分配它必须用到的权限,不要直接授予ALL PRIVILEGES。很多人图方便新建用户直接给全部权限,一旦程序出现漏洞,攻击者拿到数据库账号后可以拖库、删库,风险极高。

本文将从创建账号、精细化授权、回收权限、账号锁定、权限查看、常见坑几个方面讲解MySQL账号权限管控,覆盖MySQL5.7与MySQL8.0。

核心需求场景:

  1. 只允许账号访问指定数据库,不能看到其他库
  2. 只给查询/写入权限,禁止删除、修改表结构
  3. 保留账号可登录,但收回所有操作权限(仅保留登录能力)
  4. 限制账号只能从指定IP连接,杜绝任意地址访问

一、先搞懂MySQL账号的组成

MySQL账号格式为 '用户名'@'登录主机',用户名+主机是一个整体。

  • user@localhost:仅本地本机登录
  • user@192.168.1.100:仅指定IP登录
  • user@'%':允许任意IP远程登录(生产环境尽量避免)

重点:test@localhost 和 test@% 是两个完全独立账号,权限互不影响,操作权限时需要分别处理。

二、创建账号(不授权,仅能登录)

创建账号后默认只有USAGE权限,仅可以连接登录,没有任何数据库操作权限。

sql 复制代码
-- MySQL8.0
CREATE USER 'appuser'@'192.168.1.20' IDENTIFIED BY 'StrongPass@123';
-- MySQL5.7
CREATE USER 'appuser'@'192.168.1.20' IDENTIFIED BY 'StrongPass@123';

此时执行SHOW GRANTS FOR 'appuser'@'192.168.1.20';,结果只有:

复制代码
GRANT USAGE ON *.* TO `appuser`@`192.168.1.20`

USAGE是MySQL内置基础登录权限,无法被REVOKE回收。

三、精细化授权,按需分配权限

1. 常用权限清单

  • SELECT:查询数据
  • INSERT:新增数据
  • UPDATE:修改数据
  • DELETE:删除数据
  • CREATE / DROP:创建、删除表
  • ALTER:修改表结构
  • ALL PRIVILEGES:全部权限(生产谨慎使用)

2. 给账号指定库的查询+写入权限(推荐业务账号用法)

只允许操作business_db库下所有表,不能访问其他数据库:

sql 复制代码
GRANT SELECT,INSERT,UPDATE ON business_db.* TO 'appuser'@'192.168.1.20';
FLUSH PRIVILEGES;

business_db.*代表该库全部表;如果只授权单张表可以写business_db.table1

3. 禁止授予管理员权限

不要执行下面这种危险语句:

sql 复制代码
-- ❌不推荐,拥有全部权限
GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%';

*.*代表所有数据库所有表,等同于超级账号,一旦泄露后果严重。

四、回收账号权限:保留账号可登录,清空所有操作权限

这是很多运维人员需要的场景:账号保留、密码不变,可以正常登录,但是不能增删改查任何数据。

正确回收全部权限命令

sql 复制代码
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'appuser'@'192.168.1.20';
FLUSH PRIVILEGES;

⚠关键点:

  1. 该命令由root等管理员账号执行,不需要填写被操作账号的密码
  2. 只会收回所有数据库操作权限,账号本身不会删除,密码不变
  3. 回收完成后账号仅剩USAGE登录权限,登录后无法操作任何库表
  4. 不要遗漏GRANT OPTION,否则账号还保留转授权限

和删除用户的区别:

  • REVOKE:账号存在,能登录,无操作权限
  • DROP USER:直接删除账号,无法登录
sql 复制代码
-- 彻底删除账号(慎用)
DROP USER 'appuser'@'192.168.1.20';

五、账号锁定:禁止登录,但保留账号(MySQL8.0特有)

如果不想删除账号,又希望不让账号登录数据库,单纯REVOKE做不到,可以使用账号锁定:

sql 复制代码
--锁定账号,无法登录
ALTER USER 'appuser'@'192.168.1.20' ACCOUNT LOCK;
--解锁恢复登录
ALTER USER 'appuser'@'192.168.1.20' ACCOUNT UNLOCK;

MySQL5.7不支持ACCOUNT LOCK语法。

六、查看账号现有权限(验证权限是否生效)

sql 复制代码
SHOW GRANTS FOR 'appuser'@'192.168.1.20';

执行这条SQL可以快速确认授权/回收是否成功,日常权限变更后建议校验。

七、生产环境最佳实践与避坑指南

  1. 禁止业务账号使用%任意IP访问
    尽量固定应用服务器IP,缩小访问来源范围。
  2. 区分多个同名不同主机账号
    test@localhost和test@%是两个账号,回收权限必须分别执行REVOKE。
  3. 不要混用REVOKE与锁定功能
    • 需要账号保留登录能力,只是剥夺操作权限 → 使用REVOKE
    • 需要账号完全不能登录,临时冻结 → 使用ACCOUNT LOCK
    • 账号不再使用 → DROP USER删除
  4. 定期清理闲置账号
    定期查询mysql.user表,找出长期不用的账号,及时回收或删除,减少安全隐患。
  5. FLUSH PRIVILEGES什么时候加?
    MySQL5.7修改权限后建议加上FLUSH PRIVILEGES;刷新权限缓存;MySQL8.0执行GRANT/REVOKE自动生效,加上兼容性更好。

八、完整操作演示流程

sql 复制代码
--1.创建账号,仅可登录
CREATE USER 'appuser'@'192.168.1.20' IDENTIFIED BY 'Pass@2026';
--2.分配业务所需权限
GRANT SELECT,INSERT,UPDATE ON business_db.* TO 'appuser'@'192.168.1.20';
FLUSH PRIVILEGES;
--3.查看权限
SHOW GRANTS FOR 'appuser'@'192.168.1.20';
--4.回收全部权限,保留登录能力
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'appuser'@'192.168.1.20';
FLUSH PRIVILEGES;
--5.再次校验,仅剩登录权限
SHOW GRANTS FOR 'appuser'@'192.168.1.20';

结语

MySQL权限管控的核心思想就是最小权限,不要一劳永逸给账号全权限。根据业务实际需求分配SELECT/INSERT等有限权限;当账号暂时停用但需要保留时,使用REVOKE清空操作权限;永久废弃账号直接删除。做好权限管理,可以极大降低数据库被拖库、篡改数据的安全风险。

如果你需要,我可以补充:禁止账号创建存储过程、限制账号资源占用(最大连接数)、mysql.user表查询所有账号的相关SQL。

相关推荐
wespaul2 小时前
VeapAI 自然语言操作实战|第 05 篇:向量与召回——从知识条目到可检索资产
大数据·数据库·人工智能·milvus
一只鹿鹿鹿8 小时前
政务外网整体设计方案(PPT)
大数据·数据库·web安全·系统安全·流程图·政务
2603_965148118 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
for_ever_love__8 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
AI砖家8 小时前
安全进入 Agent Loop:2027 年 Coding Agent 的决胜点
数据库·安全·codex·vibecoding
wangqiaowq8 小时前
SQL server C盘空间占满的处理
数据库·sql
文人sec8 小时前
SQL基础入门笔记 | 从零基础到掌握核心查询语句
数据库·笔记·sql
数字新视界8 小时前
机房动环监控提升运维效率
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
SelectDB技术团队9 小时前
冷热分层从建到验:Storage Policy 创建、表级与分区级绑定、SHOW TABLETS 验证的完整命令
大数据·数据库·elasticsearch·搜索引擎·数据分析·apache doris·冷热分层
lambo mercy11 小时前
Day3:结构化输出
java·数据库·oracle