MySQL 8.0 配置用户权限最小化原则的核心是为每个应用创建独立账号,仅授予必要的数据库或表级别权限,并启用密码强度验证插件。该方案适用于所有生产环境数据库,操作风险边界在于权限回收可能导致应用报错,需在低峰期执行并保留回滚语句。
先说结论:通过创建专用用户、细化 GRANT 授权范围并开启密码策略,可有效限制泄露后的影响范围。
- 先判断:梳理应用实际需要的 SQL 操作类型,区分读写账号。
- 优先做:禁止使用 root 连接应用,为新业务创建独立用户并限制 host。
- 再验证:执行 SHOW GRANTS 确认权限范围,并模拟越权操作测试拦截效果。
命令速用版
-- 创建仅允许特定 IP 连接的用户
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'StrongPassword123!';
-- 仅授予特定库的查询和插入权限
GRANT SELECT, INSERT ON my_database.* TO 'app_user'@'192.168.1.%';
-- 查看当前用户权限
SHOW GRANTS FOR 'app_user'@'192.168.1.%';
-- 回收多余权限
REVOKE DELETE ON my_database.* FROM 'app_user'@'192.168.1.%';为什么会这样
权限配置过宽是导致数据库越权访问的直接原因,一旦账号泄露,攻击者可利用多余权限拖库或删库。
MySQL 默认安装后 root 用户拥有最高权限,若应用直接使用 root 或授予了 ALL PRIVILEGES,任何获取该凭证的攻击者都能执行 DROP DATABASE 或访问其他业务库。最小化原则要求权限粒度精确到表级别和操作类型,确保即使凭证泄露,损失也被限制在特定范围内。
分步处理
第一步:审计现有账号权限。
登录 MySQL 后执行 SELECT user, host FROM mysql.user; 和 SHOW GRANTS FOR 'user'@'host';,记录所有非系统账号的授权范围,识别是否存在 GRANT ALL 或 host 为 % 的高危账号。
第二步:创建受限新账号。
根据应用实际 IP 段创建用户,避免使用 % 允许任意主机连接。设置密码时遵循复杂度要求,MySQL 8.0 默认启用 validate_password 插件,若未启用需手动安装。
第三步:细化授权操作。
仅授予应用需要的权限,例如只读报表账号仅授予 SELECT,写入账号授予 INSERT, UPDATE。避免直接使用 GRANT ALL PRIVILEGES ON db.*,除非确需管理整个库结构。
第四步:清理旧账号权限。
确认新账号在应用侧配置生效且运行正常后,使用 REVOKE 命令回收旧账号的多余权限,或直接 DROP USER 删除不再使用的测试账号。
怎么验证是否生效
使用新账号登录数据库,尝试执行未被授权的操作,系统应返回 access denied 错误。
例如若未授予 DELETE 权限,执行 DELETE FROM table 应报错 ERROR 1142 (42000)。同时检查应用日志,确认正常业务操作无权限报错,且连接来源 IP 符合预期限制。
常见坑
1. 授权 host 为 % 导致内网任意机器可连接,应限定具体 IP 或网段。
2. 忽略存储过程权限,应用调用 procedure 时需额外授予 EXECUTE 权限。
3. 迁移脚本需要 ALTER 权限,仅授予 INSERT/UPDATE 会导致部署失败,需区分运行账号与部署账号。
常见问题
能直接删除 root 用户吗?
不建议删除 root 用户,但应禁止远程登录,保留 root 用于紧急维护并修改为仅 localhost 访问。
如何查看用户最终生效的权限?
使用 SHOW GRANTS FOR 用户命令查看,该命令会列出用户直接拥有的权限及通过角色继承的权限。
MySQL 8.0 的角色功能有助于权限管理吗?
有助于批量管理相同职责的账号权限,通过 CREATE ROLE 创建角色并授权可减少重复操作。
参考来源
MySQL Official Manual, Account Management and Security, https://dev.mysql.com/doc/refman/8.0/en/account-management.html
MySQL Official Manual, The MySQL User Account, https://dev.mysql.com/doc/refman/8.0/en/user-accounts.html