mysql数据库中如何避免权限过度分配与滥用

来源:这里教程网 时间:2026-02-28 20:42:41 作者:

创建用户时只赋予最小必要权限

MySQL 默认的

GRANT ALL PRIVILEGES
会把所有库、所有表、所有操作权限都给用户,生产环境绝对不能这么干。应该按业务模块拆分账户,比如订单服务只配
order_db
SELECT, INSERT, UPDATE
,且仅限于
orders
order_items
表。

实操建议:

CREATE USER 'app_order'@'10.20.30.%' IDENTIFIED BY 'strong_pwd_2024';
明确限定 IP 段,避免通配符
%
开放全网
授权时用
GRANT SELECT, INSERT, UPDATE ON order_db.orders TO 'app_order'@'10.20.30.%';
,不加
WITH GRANT OPTION
禁止对
mysql
系统库授任何非 DBA 权限,否则可能绕过权限校验

定期审查账号与权限变更日志

MySQL 8.0+ 默认不开启权限变更审计,

information_schema.role_table_grants
mysql.user
只反映当前状态,无法追溯“谁在什么时候加了什么权限”。没有审计就等于无法追责。

实操建议:

启用 MySQL 企业版的 Audit Log 插件,或社区版配合
general_log
(仅调试用,性能损耗大)
写脚本定期导出
SELECT user, host, account_locked, password_last_changed FROM mysql.user;
SELECT * FROM information_schema.role_table_grants;
做基线比对
DROP USER
GRANT
REVOKE
操作,在运维平台中强制走审批流,留痕到外部系统

用角色(ROLE)管理权限组而非直授用户

MySQL 8.0 引入

ROLE
后,直接给用户授一堆权限的做法已经过时。角色能解耦权限定义与用户绑定,改权限只需动角色,不用逐个用户
REVOKE/GRANT

实操建议:

先建角色:
CREATE ROLE 'role_rpt_reader';
批量授权:
GRANT SELECT ON sales_db.* TO 'role_rpt_reader';
再把角色赋给用户:
GRANT 'role_rpt_reader' TO 'bi_user'@'%';
启用角色需执行
SET DEFAULT ROLE 'role_rpt_reader' TO 'bi_user'@'%';
,否则登录后权限不生效

禁用 root 远程登录并限制超级权限使用场景

root
账户拥有
SUPER
SHUTDOWN
REPLICATION CLIENT
等高危权限,一旦泄露或被误用,可导致主从断裂、配置篡改甚至删库。线上数据库必须剥离其远程访问能力。

实操建议:

执行
DELETE FROM mysql.user WHERE user = 'root' AND host != 'localhost'; FLUSH PRIVILEGES;
清除所有非本地 root 登录点
DBA 日常维护用专用低权账号(如
dba_maint
),只在需要时临时
GRANT PROCESS, SHOW VIEW ON *.* TO 'dba_maint'@'10.20.30.%';
禁止应用代码里出现
user=root
配置项,CI/CD 流水线中加入 SQL 检查规则,匹配
user\s*=\s*['"]root['"]
并阻断发布
SELECT 
  u.User, u.Host, u.Account_locked,
  GROUP_CONCAT(DISTINCT r.Role) AS Roles,
  GROUP_CONCAT(DISTINCT CONCAT(p.Table_schema, '.', p.Table_name, ':', p.Privilege)) AS DirectPrivs
FROM mysql.user u
LEFT JOIN mysql.role_edges re ON u.User = re.Granted_role AND u.Host = '%'
LEFT JOIN mysql.roles_mapping r ON re.Granted_role = r.Role
LEFT JOIN information_schema.role_table_grants p ON r.Role = p.Grantee
GROUP BY u.User, u.Host;

权限模型越细,维护成本越高;但比起一次越权导致的数据泄漏或误删,多写几行

GRANT
和定期跑一遍检查脚本,其实更省事。真正难的是让开发和运维都接受“权限不是默认有,而是申请才有”这个前提。

相关推荐