MySQL 8.0+ 必须用 CREATE USER 和 GRANT 分步设置用户权限,禁止直接 GRANT 创建用户;需绑定地址、最小化授权、清理默认账户、启用密码策略并配合系统防火墙。

MySQL 用户权限设置必须用 CREATE USER 和 GRANT 分开执行
直接用 GRANT 创建用户在 MySQL 8.0+ 已被禁用,会报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT。必须先显式创建用户,再授权:
CREATE USER 'appuser'@'192.168.1.%' IDENTIFIED BY 'strong_pass_2024';GRANT SELECT, INSERT ON mydb.orders TO 'appuser'@'192.168.1.%';- 授权后务必运行
FLUSH PRIVILEGES;(仅在修改mysql.user表直改时才需要;用GRANT通常自动生效,但某些版本或复制环境建议执行) - 避免用
'%'通配主机,尤其不要给root配置'%'@'%'—— 这等于把 root 暴露在任意网络接口上
MySQL 本身没有内置“防火墙”,靠 bind-address 和系统级防火墙协同控制访问
MySQL 不提供类似 Web 应用防火墙(WAF)的 SQL 注入过滤功能,所谓“MySQL 防火墙”实际是两层控制:
- 配置文件中设置
bind-address = 127.0.0.1(仅本地监听),或指定内网 IP(如192.168.1.10),禁止绑定0.0.0.0(全网卡监听) - 操作系统层面用
iptables或ufw限制端口:例如只允许应用服务器 IP 访问 3306 端口:ufw allow from 192.168.1.50 to any port 3306 - 云环境(如 AWS/Aliyun)还要检查安全组规则,确保 3306 未对公网开放
-
skip-networking = ON可完全禁用 TCP 连接(仅 socket 通信),适合纯本地 CLI 管理场景,但应用无法连接
删除默认危险账户和测试库是上线前必做的三件事
MySQL 安装后自带的账户和库是攻击入口,不能跳过清理:
- 删掉匿名用户:
DELETE FROM mysql.user WHERE User = ''; - 删掉 test 库及关联权限:
DROP DATABASE IF EXISTS test;+DELETE FROM mysql.db WHERE Db LIKE 'test%'; - 重命名 root 账户(可选但推荐):
RENAME USER 'root'@'localhost' TO 'sysop'@'localhost';,避免暴力扫描常见用户名 - 检查是否有残留的
'root'@'%'或'root'@'::1',这类账户必须删或限制 IP 段
validate_password 插件启用后,SET PASSWORD 会因强度不足失败
开启密码策略插件后,弱密码(如 123456、password)会被拒绝,错误信息类似:ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。
- 确认插件已加载:
SELECT plugin_name, plugin_status FROM information_schema.plugins WHERE plugin_name LIKE 'validate%'; - 查看当前策略:
SHOW VARIABLES LIKE 'validate_password%';(重点关注validate_password.policy、.length、.mixed_case_count) - 临时调低策略仅用于测试(不推荐生产):
SET GLOBAL validate_password.policy = LOW; - 更安全的做法是生成强密码:
SELECT SHA2(RAND(), 256);或用openssl rand -base64 24外部生成
ALL PRIVILEGES 和 '%'@'%',而它真正只需要 INSERT, SELECT 在某几张表上——这个粒度差,就是多数入侵的起点。










