MySQL 数据库账户及授权

在 MySQL 数据库运维当中,账号和权限管理是安全环节里非常核心的一部分。数据库里存储着业务的核心数据,如果账号管控不当,出现弱密码、权限过大、远程 root 开放等问题,很容易造成数据泄露、误删、被入侵等严重事故。MySQL 8.0 在认证插件、密码策略、权限模型上和 5.7 版本有较大区别,本节主要围绕 MySQL8 的账号管理、密码策略、授权、回收权限、删除用户进行讲解。

1.1 密码策略

从 MySQL 8.0 开始,默认身份验证插件从 mysql_native_password 更改为 caching_sha2_password。 MySQL 5.7 的默认密码插件一直都是 mysql_native_password,它验证速度快,不需要加密连接传输密码。但是该插件底层依赖 SHA1 哈希算法,SHA1、MD5 这类算法已经被证实容易被破解,NIST 也已经建议不再使用 SHA1。

查看数据库密码相关变量:

复制代码
show variables like "%password%";
Variable_name 说明
caching_sha2_password_auto_generate_rsa_keys 是否自动生成 RSA 密钥对文件
caching_sha2_password_digest_rounds 哈希迭代回合数,默认 5000
caching_sha2_password_private_key_path RSA 私钥文件路径
caching_sha2_password_public_key_path RSA 公钥文件路径
default_password_lifetime 密码过期时间,单位天,0 代表永不过期
disconnect_on_expired_password 密码过期后是否断开连接
generated_random_password_length 自动生成随机密码长度
password_history 禁止重复使用最近 N 次历史密码
password_require_current 修改密码是否需要输入旧密码
password_reuse_interval 多少天内不能重复使用旧密码

密码强度校验插件 component_validate_password,默认不会自动安装,直接查询会返回空结果:

复制代码
SHOW VARIABLES LIKE 'validate_password%';
# Empty set (0.01 sec) 代表插件未安装

安装密码校验组件:

复制代码
INSTALL COMPONENT 'file://component_validate_password';

安装完成后再次查看:

复制代码
show variables like 'validate_password%';
Variable_name 说明
validate_password.check_user_name 禁止密码和用户名相同
validate_password.dictionary_file 弱密码字典文件路径
validate_password.length 密码最小长度,默认 8
validate_password.mixed_case_count 至少包含大小写字母总个数
validate_password.number_count 至少包含数字个数
validate_password.policy 密码安全等级
validate_password.special_char_count 至少包含特殊符号个数

密码强度等级(validate_password.policy)

  • 0 / LOW:仅校验密码长度
  • 1 / MEDIUM(默认):长度 + 数字 + 大小写 + 特殊字符
  • 2 / STRONG:MEDIUM 全部规则 + 字典文件匹配弱密码

修改密码策略示例:

复制代码
# 设置密码策略等级为LOW
set global validate_password.policy=low;
# 大小写字母最少0个
set global validate_password.mixed_case_count=0;
# 数字最少6个
set global validate_password.number_count=6;
# 特殊字符最少0个
set global validate_password.special_char_count=0;
# 密码最小长度6位
set global validate_password.length=6;

# 刷新权限,使配置生效
flush privileges;

修改用户密码语法:

复制代码
alter user 'root'@'localhost' identified by '123456';
flush privileges;

注意:MySQL8 推荐使用 alter user 修改密码,不推荐直接 update user 表的方式。

1.2 登录账户管理

MySQL8 权限管理原则:先创建用户,再分配权限 。 所有用户信息都保存在 mysql 库的 user 表中。

复制代码
# 查看当前登录用户
select user();

# 切换到mysql系统库
use mysql;

# 查看库中表
show tables;

# 查看user表结构
desc user;

# 查询所有账号、登录主机、加密后的密码
select user,host,authentication_string from user;

1.3 新建登录账户

创建用户基础语法:

复制代码
create user 'username'@'host' identified by 'password';

参数说明:

  • username:自定义用户名
  • host:允许登录的来源地址
    • localhost:仅本机登录
    • 192.168.1.%:该网段内主机可以登录
    • %:任意远程地址都可以登录(生产慎用)
  • password:账号密码

示例:

复制代码
create user 'dragon'@'localhost' identified by 'Dragon@123';

新创建的用户默认只有 USAGE 连接权限,几乎看不到业务数据库,需要手动授权。

1.4 账户授权

授权原则(生产必看)

  1. root 账号禁止使用%远程登录,只保留localhost本地登录;
  2. 业务应用账号、管理员账号分开;
  3. 最小权限原则:按需分配,一般业务账号只给 SELECT 查询权限,尽量不开 UPDATE、DELETE、DROP 高危权限;
  4. 密码复杂度符合安全策略;
  5. 定期清理闲置账号,回收或者直接删除。

查看用户权限

复制代码
# 查看当前账号权限
show grants;
# 查看指定用户权限
show grants for 'dragon'@'localhost';

新用户默认只有连接权限:GRANT USAGE ON *.* TO dragon@localhost``

GRANT 授权语法

复制代码
grant 权限列表 on 库名.表名 to '用户名'@'来源地址' [identified by '密码'];
  • 权限列表:select,insert,update,delete,create,drop,全部权限写 all
  • *.*:代表所有数据库下的所有表
  • testdb.*:仅 testdb 库下面所有表
  • testdb.t_user:仅 testdb 库中的 t_user 表

示例 1:创建 test1,授予查询所有库表权限

复制代码
create user 'test1'@'localhost' identified by '123456';
grant select on *.* to 'test1'@'localhost';

示例 2:创建 test2,允许 192.168.56.% 网段登录,拥有 select、create 权限

复制代码
create user 'test2'@'192.168.56.%' identified by '123456';
grant select,create on *.* to 'test2'@'192.168.56.%';

示例 3:all 权限和 with grant option 直接授予all权限不包含给其他用户授权的能力。

复制代码
create user 'test3'@'%' identified by '123456';
grant all on *.* to 'test3'@'%';

此时 test3 尝试给其他账号授权会报错 Access denied。 如果需要该用户具备授权别人的能力,加上 with grant option:

复制代码
grant all on *.* to 'test3'@'%' with grant option;

之后 test3 就可以新建用户、给其他账号分配权限。

补充:部分版本 root 执行授权报错,需要先给 root 赋予 system_user 权限

复制代码
grant system_user on *.* to 'root'@'localhost';

1.5 回收权限

REVOKE 回收权限语法,和 grant 结构类似,关键字to改为from:

复制代码
revoke 权限列表/all on 库名.表名 from '用户名'@'来源地址';

示例:

复制代码
# 回收test4的select权限
revoke select on *.* from 'test4'@'%';
# 回收test3全部权限
revoke all on *.* from 'test3'@'%';
# 回收test2全部权限
revoke all on *.* from 'test2'@'192.168.56.%';
# 回收test1全部权限
revoke all on *.* from 'test1'@'localhost';

1.6 删除账户

删除用户语法:

复制代码
drop user '用户名'@'访问主机名';

示例:

复制代码
drop user 'test3'@'%';
drop user 'test4'@'%';
drop user 'test2'@'192.168.56.%';
drop user 'test1'@'localhost';

注意:删除用户必须带上 host 部分,'test1'@'localhost' 和 'test1'@'%' 是两个完全独立账号。

相关推荐
时间售卖铺27 分钟前
Chrony与SSH实战:精准时间同步与安全远程登录
运维·安全·云原生·ssh
微订校园外卖系统38 分钟前
校园代取快递系统选型:现成系统与定制开发的技术核对项
大数据·运维·人工智能·外卖系统·本地生活·微订
QXWZ_IA43 分钟前
管道GIS测绘如何实现自动化成图:三种成图方式怎么选
运维·人工智能·安全·自动化
羑悻的小杀马特43 分钟前
Redis持久化三剑客:RDB二进制快照、AOF文本日志、混合模式如何守护你的数据安全?
数据库·redis·缓存·aof·持久化存储·rdb
一条破秋裤1 小时前
【1112】Linux中断【整理】
linux·运维·服务器
小呆爱发呆1 小时前
第三章 MySQL 库表操作
数据库·mysql·adb
分布式存储与RustFS1 小时前
OpenObserve 的日志别堆本地盘:用 RustFS 当它的对象存储底座
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
时间的拾荒人2 小时前
Redis 进阶实战:渐进式遍历、持久化机制与事务详解
数据库·redis·缓存
普通人62 小时前
MySQL_FIND_IN_SET函数详解
android·数据库·mysql