ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MySQL 账号权限体系:从 everyone root 到最小权限实践

MySQL 账号权限体系:从 everyone root 到最小权限实践
个人主页: > for_ever_love__ <(欢迎各位大佬莅临😊)
其他栏目: > 大模型开发从0到1 <
其他栏目: > iOS项目总结大全 <
其他栏目: > 我想学python了 <
其他栏目: > iOS UI <

文章目录

  • MySQL 账号权限体系:从 everyone root 到最小权限实践
    • MySQL 权限的两个层级
    • 账号分层设计
    • 最小权限的三条落地纪律
    • 权限查询与审计
    • 典型事故复盘:一个 over-privileged 的代价
    • 迁移到 8.0 的动态权限
    • 小结

MySQL 账号权限体系:从 everyone root 到最小权限实践

生产库权限管理失控的典型画面:应用连库用 root、测试连生产用同一个 over-privileged 账号、离职员工的账号还在、GRANT ALL满天飞。出一次事(误删、注入、拖库),损失程度完全由权限体系决定。这篇文章讲 MySQL 权限体系的设计:账号分层、权限最小化、以及落地时的审计机制。

MySQL 权限的两个层级

全局权限(ON *.*):作用于整个实例。

GRANTALLPRIVILEGESON*.*TO'admin'@'%';-- 万恶之源,排第二GRANTPROCESS,REPLICATIONCLIENT,REPLICATIONSLAVEON*.*TO'monitor'@'10.0.0.%';

库/表/列级权限:

GRANTSELECT,INSERT,UPDATEONbiz_db.*TO'app_rw'@'10.0.0.%';GRANTSELECT(id,name)ONbiz_db.customerTO'app_ro'@'10.0.0.%';-- 列级GRANTSELECTONbiz_db.ordersTO'report'@'10.0.0.%';

还有三个特殊权限永远单独考量:GRANT OPTION(能转授权限,不给)、SUPER(8.0 已拆成细粒度动态权限,慎给)、FILE(读写服务器文件,约等于 shell)。

关键认知:MySQL 的权限粒度止步于库表列 + 过程函数触发器级别,没有行级权限、没有列值过滤("只看自己的订单"这类要应用层实现)。权限体系是粗粒度防线,细粒度永远靠应用。

账号分层设计

生产实例的账号矩阵,按角色划分:

角色权限用途来源
root/localhostALL仅本地应急维护默认
adminALL + GRANTDBA 管理,人使用,应用禁用新建
app_rwCRUD on 业务库应用主库连接新建
app_roSELECT on 业务库应用读库连接新建
replREPLICATION SLAVE, SLAVE MONITOR复制账号新建
backupRELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT, BACKUP_ADMINXtraBackup/mydumper新建
monitorPROCESS, REPLICATION CLIENT, SELECT on mysql 系统库监控采集新建
etlSELECT + 必要写权限 on 指定库数据同步新建

创建的标准写法:

-- 强策略:caching_sha2_password(8.0 默认)CREATEUSER'app_rw'@'10.0.0.%'IDENTIFIEDBY'xxx'WITHMAX_QUERIES_PER_HOUR100000MAX_USER_CONNECTIONS100PASSWORD EXPIREINTERVAL90DAY;GRANTSELECT,INSERT,UPDATE,DELETEONbiz_db.*TO'app_rw'@'10.0.0.%';-- 复制账号:必须 REPLICATION SLAVE 系统权限CREATEUSER'repl'@'10.0.0.%'IDENTIFIEDBY'yyy';GRANTREPLICATIONSLAVE,REPLICATIONCLIENTON*.*TO'repl'@'10.0.0.%';FLUSHPRIVILEGES;

@'10.0.0.%'是来源 IP 白名单——比@'%'(任何 IP)安全一个量级。应用连接固定网段的,配到网段甚至单 IP。来源限制是被低估的防线:即使密码泄露,攻击者的机器连不上也白搭。

最小权限的三条落地纪律

纪律一:按功能拆账号,不按"读写"粗分。

很多团队只配 app_rw 和 app_ro 两个。进一步:ETL 账号、报表账号、消息消费者账号各自独立。某天拖库事件发生时,日志里能分清"是哪个系统的连接干的"——共用账号等于全员共享指纹。

纪律二:敏感表收紧到列级。

-- customer 表的手机号、身份证列,应用主链路只读 id/name/statusGRANTSELECT(id,name,status)ONbiz_db.customerTO'app_rw'@'10.0.0.%';-- 敏感字段的读取走单独的高权限账号或脱敏视图CREATEVIEWbiz_db.customer_maskedASSELECTid,name,CONCAT(LEFT(phone,3),'****',RIGHT(phone,4))ASphoneFROMcustomer;GRANTSELECTONbiz_db.customer_maskedTO'app_ro'@'10.0.0.%';

脱敏视图是低成本高价值的手段:查敏感数据的入口收窄成视图,视图里做脱敏,泄露面直接砍半。

纪律三:定期清理。

离职、项目下线、临时账号——不清理的权限表就是债务。三个自动化点:

-- 1. 列出所有非 root 超级账号(应该几乎没有)SELECTuser,hostFROMmysql.userWHERESuper_priv='Y'ANDuser!='root';-- 2. 列出 90 天未使用的账号(需要 performance_schema 或审计插件)-- 3. 列出密码过期的账号(开了 PASSWORD EXPIRE 的场景)SELECTuser,host,password_expiredFROMmysql.userWHEREpassword_expired='Y';

权限查询与审计

日常审计三张表:

-- 1. 所有人的完整权限SHOWGRANTSFOR'app_rw'@'10.0.0.%';SELECT*FROMmysql.userWHEREuserNOTIN('mysql.infoschema',...);-- 全量用户-- 2. 谁在连(实时)SELECT*FROMinformation_schema.processlist;-- 或 sys.processlist-- 3. 谁连过、从哪连(历史)SELECT*FROMperformance_schema.host_cache;-- 连接来源统计

审计插件(下篇专讲)补上"谁执行了什么"——权限体系管"能不能做",审计管"做了什么",两层都要。

典型事故复盘:一个 over-privileged 的代价

真实案例:电商团队所有服务共用app_rw,权限是GRANT ALL ON biz_db.*。某天一个订单服务的接口被注入,攻击者拿到连接串后执行:

-- 直接删了整个用户表DROPTABLEbiz_db.vip_user;

如果当时 vip_user 只对服务账号开放SELECT, INSERT, UPDATE(不需要 DELETE/DROP),这条语句会被权限拒绝;如果再收紧到列级,连"导出全表"都难。过宽的权限把一次接口注入放大成一次数据灾难。

事后整改:按服务拆账号、收回 DDL、敏感表列级、连接来源限 IP、审计插件上线。每个措施都不复杂,难的是在没有事故时就有动力做——权限治理的价值恰好在出事时才兑现。

迁移到 8.0 的动态权限

MySQL 8.0 把 SUPER 拆成 50+ 个动态权限,这是好事——细粒度授权:

-- 只需要"看主从状态"的监控账号,不用给 SUPERGRANTSYSTEM_VARIABLES_ADMIN,SESSION_VARIABLES_ADMINON*.*TO'monitor'@'%';-- 需要 kill 连接的运维脚本账号GRANTCONNECTION_ADMINON*.*TO'ops'@'10.0.0.%';

升级路径上,逐个审 old SUPER 账号的实际用途,替换成最小动态权限组合。这个工作没有捷径,只能一个账号一个账号过。

小结

MySQL 权限管理的核心是分层与最小化:应用、复制、备份、监控、ETL 各用独立账号,来源 IP 限制,库表列三级授权,敏感数据走脱敏视图,SUPER 和 FILE 单独审批。定期清理 + host_cache/审计插件是治理闭环。权限体系防不住 SQL 注入(那是下篇的事),但它决定注入的危害上限——把每个账号的能力圈划到"完成本职工作所需的最小集合",是 DBA 能做的最划算的安全投资。

返回列表