空密码风险源于mysql.user表中authentication_string为空或null的记录,需手动筛查并重置密码或删除;validate_password插件必须显式安装且配置正确才生效,仅set global设置重启后失效,弱密码账户不会自动更新,须人工重置。

空密码用户不是配置问题,是数据问题
MySQL 没有 AllowNoPassword 这种配置项,搜到它基本是混淆了客户端命令行的 --no-defaults 或某些 GUI 工具的误传。真实风险来自 mysql.user 表里 authentication_string 为空或为 NULL 的记录——只要认证插件(如 caching_sha2_password)没明确拒绝,就可能被空密码登录。
必须手动筛查并处理:
- 执行
SELECT user, host, authentication_string FROM mysql.user WHERE authentication_string = '' OR authentication_string IS NULL;,结果非空即存在风险账户 - 对每个结果行,用
ALTER USER 'user'@'host' IDENTIFIED BY 'strong_password';设密,或直接DROP USER 'user'@'host';删除无用账号 - 特别注意匿名用户:
DROP USER IF EXISTS ''@'localhost'; DROP USER IF EXISTS ''@'%'; - 执行
FLUSH PRIVILEGES;立即生效
validate_password 插件不装等于没设
MySQL 默认完全不校验密码强度,123456、password 都能直接通过。插件必须显式安装且加载成功,否则所有策略参数都是摆设。
检查和安装步骤:
- 查是否已加载:
SELECT * FROM information_schema.plugins WHERE plugin_name = 'validate_password';,返回空行说明未安装 - MySQL 5.7:
INSTALL PLUGIN validate_password SONAME 'validate_password.so'; - MySQL 8.0.13+:
INSTALL COMPONENT 'file://component_validate_password'; - 装完立刻验证:
SHOW VARIABLES LIKE 'validate_password%';应返回一整组变量,而不是空结果 - 若报
Plugin 'validate_password' is not loaded,说明系统缺失插件文件,需重装mysql-community-server(CentOS)或mysql-server(Ubuntu)包
策略参数写错位置或名字,重启就失效
运行时用 SET GLOBAL 设置的策略(如 SET GLOBAL validate_password.policy = MEDIUM;)在 MySQL 重启后全部丢失。必须写进配置文件才持久。
但变量名在不同版本差异很大:
- MySQL 5.7:配置项是
validate_password_length、validate_password_policy - MySQL 8.0+ 多数版本要求用带点号的格式:
validate_password.length、validate_password.policy - 写错格式(比如在 8.0+ 里写成
validate_password_length)会静默失败,SHOW VARIABLES里也看不到对应值 - 必须加在
my.cnf的[mysqld]段下,例如:validate_password.policy = MEDIUM<br>validate_password.length = 12<br>validate_password.mixed_case_count = 2
弱密码账户不会自动更新,只能人工重置
validate_password 插件只对 CREATE USER 和 ALTER USER ... IDENTIFIED BY 生效,对已存在的弱密码账户完全无感。哪怕你把策略调成 STRONG,root 还是能继续用 123 登录。
所以加固必须两步走:
- 先用插件堵住新账户入口
- 再人工排查存量账户:
SELECT user, host FROM mysql.user WHERE LENGTH(authentication_string) (粗筛,因哈希长度通常 ≥ 40) - 对疑似弱口令用户,强制重置:
ALTER USER 'user'@'host' IDENTIFIED BY 'NewStrongPass!2026'; - 特别留意
root账户是否仍用auth_socket插件(Ubuntu/Debian 常见),查SELECT plugin FROM mysql.user WHERE user='root';,若是,先切回mysql_native_password:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '...';
最易被忽略的是:插件启用后,skip-grant-tables 仍能绕过一切校验。上线前务必确认该启动参数未被误开启,否则所有密码策略形同虚设。











