创建最小权限账号必须显式执行CREATE USER再GRANT授权,禁用隐式创建;限定IP段、强制SSL、设密码过期;授具体库表权限,禁用ALL PRIVILEGES;密码须从密钥服务注入,禁硬编码;验证host匹配与权限边界。

创建最小权限账号必须用 CREATE USER + GRANT 分开执行
直接用 GRANT 语句隐式创建用户在 MySQL 8.0+ 已被弃用,且容易漏掉密码策略或账户锁定配置。生产环境必须显式创建再授权,否则可能触发 ERROR 1410 (42000): You are not allowed to create a user with GRANT。
实操建议:
- 先用
CREATE USER 'app_user'@'10.20.30.%' IDENTIFIED BY 'strong_pass_2024' REQUIRE SSL PASSWORD EXPIRE INTERVAL 90 DAY;显式建户,限定 IP 段、强制 SSL、设置密码过期 - 再用
GRANT SELECT, INSERT, UPDATE ON myapp_db.* TO 'app_user'@'10.20.30.%';授予具体库表的有限操作权 - 严禁使用
GRANT ALL PRIVILEGES ON *.*或对mysql系统库授予权限 - 执行完立刻
FLUSH PRIVILEGES;(仅 MySQL 5.7 及更早需显式调用;8.0+ 多数情况自动刷新,但保留更稳妥)
应用连接字符串里不能硬编码 root 或空密码
常见错误是开发时用 root 账号调试,上线后忘记改连接字符串,导致数据库凭据泄露风险陡增。一旦容器镜像、日志或配置文件被误提交,等于直接交出数据库控制权。
实操建议:
- 连接字符串中的用户名必须是专用账号,如
app_user,绝不能是root、admin或mysql - 密码必须从环境变量或密钥管理服务(如 HashiCorp Vault、AWS Secrets Manager)注入,禁止写死在代码或
.env文件中 - 验证方式:运行
grep -r 'root.*password\|localhost.*3306' ./src,确保无匹配结果 - MySQL 客户端连接测试时,用
mysql -u app_user -p -h db-prod.internal -D myapp_db手动验证权限边界——比如执行DROP TABLE users;应明确报错ERROR 1142 (42000): DROP command denied to user 'app_user'@'10.20.30.5'
账号名和 host 组合决定实际可连范围,别信 localhost 就安全
'app_user'@'localhost' 和 'app_user'@'127.0.0.1' 在 MySQL 中是两个完全不同的账号,前者走 Unix socket,后者走 TCP。很多应用默认连 127.0.0.1,结果发现权限不生效,就是 host 写错了。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
实操建议:
- 生产环境一律用 IP 段或域名限制,例如
'app_user'@'10.20.30.%'(对应 K8s Pod CIDR)或'app_user'@'app-svc.default.svc.cluster.local' - 避免用
%通配符,尤其不能写成'app_user'@'%';如需跨网段,精确到子网掩码,如'app_user'@'10.20.%.%' - 检查当前生效账号:执行
SELECT User, Host FROM mysql.user WHERE User = 'app_user';,确认返回的Host值与应用实际发起连接的源地址一致 - 注意 DNS 解析延迟可能导致
host匹配失败,优先用 IP,慎用域名
定期轮换密码但别改错账号名,否则应用直接中断
运维同学常以为“改密码=改账号”,执行 ALTER USER 'app_user'@'10.20.30.%' IDENTIFIED BY 'new_pass'; 后没同步更新应用配置,结果所有请求瞬间报 Access denied for user 'app_user'@'10.20.30.5'。
实操建议:
- 密码轮换必须配合配置发布流程:先更新密钥管理服务 → 再滚动重启应用 → 最后在 DB 执行
ALTER USER - 临时过渡可用双账号方案:新建
app_user_v2并赋相同权限,等应用切流完成后再删旧账号 - 监控告警项应包含:
Aborted_connects突增、Threads_connected长期为 0、慢查询日志中大量Access denied记录 - MySQL 8.0+ 支持密码历史策略:
ALTER USER 'app_user'@'10.20.30.%' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 180 DAY;,防止重复使用旧密码
权限粒度、host 精确性、密码生命周期这三件事,任何一个没卡住,安全策略就形同虚设。最麻烦的不是设不设,而是设了但没验证它真在生效。

















