查用户和权限:先看清楚谁有啥权限
权限漏洞往往不是“没权限”,而是“权限太多”或“配错了人”。第一步不是修,是看:
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,远程照样连不上,你会误判成“权限没生效”。
