mysql权限分配最佳实践有哪些_mysql项目安全经验总结

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

只给最小必要权限,别用
GRANT ALL PRIVILEGES

生产环境里最常犯的错,就是建个账号顺手执行

GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%'
。这等于把数据库当裸奔现场——一旦应用被注入或配置泄露,攻击者能删库、读取系统表、甚至写入文件(如果开了
FILE
权限)。

实操建议:

按模块/服务单独建用户,比如
shop_order_rw
report_ro
,名字自带用途和权限范围
写操作只授
SELECT, INSERT, UPDATE, DELETE
,且限制到具体库+表:
GRANT SELECT, INSERT ON shop_db.orders TO 'shop_order_rw'@'10.20.30.%'
读报表类账号一律加
WITH GRANT OPTION
禁用,防止权限扩散
临时排查用的高权账号,设
MAX_QUERIES_PER_HOUR 0
但必须配
PASSWORD EXPIRE INTERVAL 1 DAY

慎用通配符主机名,优先绑定内网 IP 段

'user'@'%'
看着省事,实际等于开放所有网络入口。MySQL 默认不加密传输认证包(除非强制
REQUIRE SSL
),中间人可截获密码哈希重放。

实操建议:

应用服务器固定 IP 的,直接写
'appuser'@'192.168.5.12'
;用 K8s 或云环境的,用 CIDR 段:
'appuser'@'10.100.0.0/255.255.0.0'
绝对不用
'%' + 密码弱策略
组合。若必须用
%
,强制要求
ALTER USER 'u'@'%' REQUIRE SUBJECT '/CN=app-server'
做证书校验
测试环境也别图省事开
'%',
本地开发用
'localhost'
(注意:它走 socket 连接,和
127.0.0.1
是两个用户)

避免用 root 或 mysql.sys 等内置账号跑应用

root 账号密码常被硬编码进配置文件或环境变量,一泄露就是全盘沦陷;

mysql.sys
虽默认无密码,但拥有
INFORMATION_SCHEMA
和性能视图读取权,配合
SELECT ... INTO OUTFILE
可导出敏感元数据。

实操建议:

部署脚本里禁止出现
mysql -uroot -p...
连接应用库,改用专用账号
检查
SELECT user, host FROM mysql.user
,删掉所有
host = '%'
user IN ('root', 'mysql.sys', 'debian-sys-maint')
的行
SHOW GRANTS FOR 'appuser'@'10.20.30.%'
定期审计,重点看是否意外继承了
PROXY
权限或
CREATE USER

权限变更必须走 SQL 变更流程,禁用手工
FLUSH PRIVILEGES

直接改

mysql.user
表再刷权限,是 MySQL 最隐蔽的坑之一——表结构变更可能被复制中断、GTID 不一致,且
FLUSH PRIVILEGES
不会同步到从库。

实操建议:

所有权限增删改,统一走
GRANT
/
REVOKE
语句,并纳入 DBA 审批的 SQL 变更单
自动化部署时,用
mysql -e "GRANT ..."
而非先
INSERT INTO mysql.user
FLUSH
从库上执行
STOP SLAVE; SET sql_log_bin=0; GRANT ...; START SLAVE;
属于高危操作,除非明确知道该权限仅用于从库监控

权限不是设一次就完事的事。MySQL 的

max_connections
wait_timeout
等资源限制参数,和权限策略一样影响安全边界——比如一个长期空闲的高权连接,可能成为未授权访问的跳板。真正难的是把权限逻辑嵌进 CI/CD 流程里,让每次应用发布自动校验账号权限是否收缩。

相关推荐