mysql root用户权限如何限制_mysql安全最佳实践

来源:这里教程网 时间:2026-02-28 20:52:41 作者:

root用户不该直接用于应用连接

MySQL 的

root
用户默认拥有所有权限,包括
DROP DATABASE
SHUTDOWN
FILE
等高危操作。生产环境里用
root
跑应用或中间件,等于把数据库的“物理钥匙”交给了业务代码——一旦应用被注入或配置泄露,整个实例可能瞬间清空。

实操建议:

为每个应用单独创建专用账号,例如
app_payment
,只赋予
SELECT
INSERT
UPDATE
DELETE
权限,且限定在对应数据库(如
payment_db
)内
禁用
root
的远程登录:
DELETE FROM mysql.user WHERE User='root' AND Host!='localhost'; FLUSH PRIVILEGES;
若必须远程管理,改用跳板机 + SSH 隧道,或通过
mysql -h 127.0.0.1 -u root
(走 TCP)而非
-h localhost
(走 socket),再配合防火墙限制源 IP

如何安全地回收 root 的 FILE 和 SUPER 权限

FILE
权限允许读写服务器任意文件(如
SELECT ... INTO OUTFILE
可导出
/etc/passwd
),
SUPER
则能 kill 线程、修改全局变量、绕过 binlog 控制——这两项是提权和持久化攻击的关键跳板。

MySQL 8.0+ 不支持直接

REVOKE FILE ON *.* FROM 'root'
(因为它是超级用户隐式权限),必须从根源限制:

启动时加参数
--secure-file-priv=/var/lib/mysql-files/
,强制
LOAD DATA INFILE
只能读该目录下的文件
移除
root
SUPER
权限需先启用
skip-grant-tables
模式重置,但更稳妥的做法是:用
CREATE USER 'dba_admin'@'localhost' IDENTIFIED BY 'xxx' WITH ADMIN OPTION;
创建替代管理员,并确保其不带
FILE
检查残留风险:
SELECT User,Host,File_priv,Super_priv FROM mysql.user WHERE User='root';
,输出应为
N
NULL

密码策略与认证插件要硬性启用

默认的

mysql_native_password
插件不强制复杂度,且旧版本允许空密码。MySQL 5.7+ 提供
validate_password
插件,但需手动加载并设阈值。

执行顺序不能错:

先加载插件:
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
再设强度:
SET GLOBAL validate_password.policy = MEDIUM;
(要求至少 1 个大写、1 个小写、1 个数字、1 个特殊字符,长度 ≥ 8)
root
强制改密:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'NewPass!2024';
验证是否生效:
SELECT VALIDATE_PASSWORD_STRENGTH('weak'); → 0
SELECT VALIDATE_PASSWORD_STRENGTH('StrongP@ss2024'); → 100

监听地址和网络层必须收缩

MySQL 默认绑定

0.0.0.0:3306
,只要端口开放,就可能被暴力破解或未授权访问。很多运维人员只改了
bind-address
却忘了防火墙同步。

关键动作:

配置文件中明确写
bind-address = 127.0.0.1
(仅本地),或指定内网 IP(如
192.168.10.5
),绝不要留空或写
*
操作系统级封堵:
ufw deny 3306
(Ubuntu)或
firewall-cmd --permanent --remove-port=3306/tcp
(CentOS)
确认无其他监听进程:
netstat -tlnp | grep :3306
,输出中的
Local Address
应为设定 IP,不是
*:3306
如果用了云服务(如阿里云 RDS),安全组规则比 MySQL 自身配置更优先,务必检查入方向是否只放行 DBA 跳板机 IP

真正难的是权限收敛后的故障定位——比如某个凌晨三点的慢查询突然卡住,而你又没留

PROCESS
权限给监控账号,这时候连
SHOW PROCESSLIST
都看不到。所以最小权限不是一味砍,而是按角色分层:dba\_readonly、dba\_admin、app\_writer,每层之间用视图或代理做隔离。

相关推荐