mysql权限加固需四步:先查账户与权限,重点排查空密码、'%'主机和匿名用户;再删冗余、锁通配、改认证插件;然后用create user+grant重授最小权限;最后从目标ip连接验证业务语句,并备份权限表。

查用户和权限:先看清楚谁有啥权限
权限漏洞往往不是“没权限”,而是“权限太多”或“配错了人”。第一步不是修,是看:SELECT User, Host, authentication_string FROM mysql.user; 能看到所有账户,重点盯三点:空密码(authentication_string为空或为'')、Host为'%'的宽泛账户、User为空(''@'localhost')的匿名用户。再对每个关键用户执行 SHOW GRANTS FOR 'app_user'@'%';,确认是否真给了DROP、FILE、GRANT OPTION这类高危权限——普通应用账号不该有。
删冗余、锁通配、改认证插件:三步收紧入口
发现风险就立刻动手,别等下次扫描:
• 删除匿名用户:DROP USER ''@'localhost';
• 收窄远程访问范围:把'user'@'%'改成具体网段,比如'user'@'192.168.5.%',避免暴露给公网
• 修复登录失败问题:如果mysql -u root -p报错“Access denied”,很可能是plugin字段为auth_socket,但你用的是密码登录。进安全模式后执行:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_pass';
注意:MySQL 8.0+ 不再支持PASSWORD()函数,必须用ALTER USER ... IDENTIFIED WITH语法,否则会报错。
重授最小权限:别直接INSERT mysql.user
恢复数据后权限全丢?别手贱往mysql.user表里INSERT字段。不同版本字段差异大(比如 5.7 有password字段,8.0 只有authentication_string),极易导致后续无法登录。正确做法是重建逻辑:
• 创建用户:CREATE USER 'api_user'@'10.10.20.%' IDENTIFIED BY 'strong_pwd_2026';
• 授最小集权限:GRANT SELECT, INSERT, UPDATE ON finance_db.orders TO 'api_user'@'10.10.20.%';
• 刷新生效:FLUSH PRIVILEGES;
如果原环境有导出的权限SQL(如用mysqldump --no-data --skip-triggers mysql备份过),优先执行它——比手动一条条写更可靠。
验证和防复发:连得上≠用得对
修完必须验证,而且要按真实路径走:
• 用目标用户从目标IP连:mysql -u api_user -p -h10.10.20.5,不能只在localhost试
• 进去后立刻跑业务语句:SELECT COUNT(*) FROM orders WHERE status = 'pending' LIMIT 1;,光SHOW DATABASES;不够,得测实际操作
• 把mysqldump mysql > mysql_permissions_backup.sql加入日常运维脚本——权限表不是“一次配置终身有效”,升级、误操作、复制同步都可能覆盖它
最容易被忽略的一点:权限修复后,别忘了检查bind-address和防火墙。即使'user'@'%'存在,若my.cnf里bind-address = 127.0.0.1,远程照样连不上,你会误判成“权限没生效”。










