MySQL 默认 root 账户必须改密码且禁用空密码登录
安装后未改密的
root@localhost是最大风险点,尤其在云服务器或 Docker 环境中,扫描器几秒就能爆破成功。MySQL 8.0+ 默认启用
validate_password插件,但不会自动强制复杂度——得手动检查并设阈值。 执行
SHOW VARIABLES LIKE 'validate_password%';查看当前策略,重点确认
validate_password.policy不为
LOW设强策略:
SET GLOBAL validate_password.policy = MEDIUM;(要求含大小写字母、数字、特殊字符,最小长度 8) 重置 root 密码:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的高强度密码';立刻执行
FLUSH PRIVILEGES;生效,否则新密码不生效
禁止 root 远程登录,新建专用账号并限制 IP 和权限
允许
root@'%'登录等于把数据库大门钥匙挂在公网门口。生产环境应彻底禁用远程 root,并为每个应用创建最小权限账号。 删掉所有非本地 root 远程实例:
DROP USER 'root'@'%';(注意:不是
DELETE FROM mysql.user,那是危险操作) 新建账号示例:
CREATE USER 'app_user'@'192.168.10.5' IDENTIFIED BY 'AppPass2024!';(IP 写应用服务器真实内网 IP) 只授必要库表权限:
GRANT SELECT, INSERT, UPDATE ON myapp_db.* TO 'app_user'@'192.168.10.5';,绝不给
GRANT OPTION或
mysql库权限 确认无多余账号:
SELECT user, host FROM mysql.user;,删掉
''@'localhost'(匿名用户)等默认残留
关闭不需要的服务端功能,降低攻击面
MySQL 启动时默认开启一堆危险功能,比如本地文件读写、外部脚本加载、旧协议支持,这些在绝大多数业务里根本用不到,却常被用于提权或逃逸。
启动时加参数禁用:--secure-file-priv=/tmp/(限制
LOAD DATA INFILE只能读指定目录),或设为
NULL彻底禁用 禁用符号链接:
--skip-symbolic-links(防绕过 datadir 限制) 禁用旧认证插件:
default_authentication_plugin=mysql_native_password(避免客户端降级到不安全的
mysql_old_password) 关闭远程管理端口(如果不用 MySQL Router 或 ProxySQL):
skip-networking=ON(仅限本地 Unix socket 访问)
定期审计日志与错误日志,别让告警沉没
很多团队开了
general_log或
slow_query_log,但从来不看;更常见的是
error_log权限设错,导致 MySQL 无法写入而静默失败。 确保
log_error指向可写路径,如
/var/log/mysql/error.log,且属主是
mysql:mysql开启连接审计(MySQL 8.0+):
INSTALL COMPONENT 'file://component_audit_api_message';,再设
audit_log_policy=ALL慎开
general_log:它记录每条 SQL,IO 压力极大,仅调试时临时启用,用完立刻关:
SET GLOBAL general_log = OFF;用
mysqldumpslow分析慢日志,重点关注
Rows_examined过高、未走索引的查询,它们既是性能瓶颈也是注入温床
MySQL 安全加固不是配完就一劳永逸的事——
host字段通配符、临时表空间权限、备份账号复用生产密码、SSL 配置未验证证书链,这些细节在每次版本升级或架构变更时都可能被绕过。
