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

10次阅读

生产环境应遵循最小权限原则:按服务建专用账号(如shop_order_rw),仅授予必要库表的select/INSERT/UPDATE/delete权限,禁用’%’主机名、root及系统账号,权限变更须走GRANT/REVOKE流程并纳入sql变更审批。

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

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

生产环境里最常犯的错,就是建个账号顺手执行 GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%'。这等于把数据库当裸奔现场——一旦应用被注入或配置泄露,攻击者能删库、读取系统表、甚至写入文件(如果开了 FILE 权限)。

实操建议:

  • 按模块/服务单独建用户,比如 shop_order_rwreport_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.userFLUSH
  • 从库上执行 STOP SLAVE; SET sql_log_bin=0; GRANT ...; START SLAVE; 属于高危操作,除非明确知道该权限仅用于从库监控

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

text=ZqhQzanResources