Linux实战之MySQL数据库——MySQL8安全机制

By | 2020年3月27日

MySQL8安全机制

MySQL8密码恢复

(1) 停止服务
[root@nfs01 ~]# systemctl stop mysqld
(2) 修改配置文件
[root@nfs01 ~]# vim /etc/my.cnf
socket=/var/lib/mysql/mysql.sock
skip-grant-tables	#新增
(3) 重启服务
[root@nfs01 ~]# systemctl restart mysqld
(4) 登录数据库(不需要输入密码)
[root@nfs01 ~]# mysql -uroot -p
mysql> flush privileges;	#刷新权限
mysql> alter user 'root'@'localhost' IDENTIFIED BY 'Zhao123@com';	#修改密码
(5) 停止服务
[root@nfs01 ~]# systemctl stop mysqld
(6) 修改配置文件
[root@nfs01 ~]# vim /etc/my.cnf
socket=/var/lib/mysql/mysql.sock
#skip-grant-tables #注释掉,不安全
(7) 重启服务
[root@nfs01 ~]# systemctl restart mysqld

【MySQL5.7修改密码】
mysql> use mysql
mysql> update user set authentication_string=password('123456') where
user='root' and Host = 'localhost';

mysql8.0新特性

Role规则

可以认为是一个权限的集合,这个集合有一个统一的名字,就是Role名,可以为多个账户赋予统一的某个Role的权限,而权限的修改可以直接通过修改Role来实现,而无需每个账户逐一GRANT权限,大大方便了运维和管理

Role可以被创建,修改和删除,并作用到其所属于的账户上

权限控制

账户与安全变更,增加新的安全策略,增加角色功能
(1)mysql8.0创建用户和用户授权的命令是分开执行的(语法的定义更加清晰)

mysql> create user 'test'@'%' identified by 'Cloudbu@123';
mysql> grant all privileges on *.* to 'test'@'%';

mysql5.7创建用户,创建和授权可以一步进行
mysql> grant all privileges on *.* to 'test'@'%' identified by 'Cloudbu@123';

(2)认证的插件更新
mysql8.0中默认的身份认证插件是caching_sha2_password,替代了之前的mysql_navtive_password,这种新的认证会更加安全

mysql> show variables like 'default_authentication%';	#通过系统变量查询
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | caching_sha2_password |
+-------------------------------+-----------------------+
1 row in set (0.00 sec)

mysql> select User,Host,Plugin from mysql.user;	#通过用户表查看plugin这一列
+------------------+-----------+-----------------------+
| User             | Host      | Plugin                |
+------------------+-----------+-----------------------+
| anliu01          | %         | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
5 rows in set (0.01 sec)

如果连接的客户端比较老旧没有升级,在连接mysql8.0时候可能会认证错误

如果想要使用之前老的认证方式可以在/etc/my.cnf配置文件里将default-authentication-plugin这段开启,然后重启数据库

如果想对某个用户使用老的认证方式,可以使用以下语句:

mysql> alter user 'test'@'%' identified with mysql_native_password by 'Cloudbu@123';	#with后面跟上插件
mysql> select User,Host,Plugin from mysql.user;

(3)密码管理的策略增强

mysql8.0开始用几个系统变量来实现限制重复使用以前的密码

查看密码管理相关的系统变量

mysql> show variables like 'password%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| password_history         | 0     |
| password_require_current | OFF   |
| password_reuse_interval  | 0     |
+--------------------------+-------+
3 rows in set (0.00 sec)

password_history:password_history = 3 表示新密码不能和最近使用过3次的密码相同;0不限制。
password_reuse_interval:password_reuse_interval = 60 表示新密码不能和60天之内的密码相同,默认值为0,不限制。
password_require_current:默认值OFF,当值为ON用户修改密码需要提供当前密码。

设置方式
在mysql8.0增加了新特性就是在线修改系统变量,并将修改后的持久化到磁盘,重启服务依然有效,重新生成一个新的配置文件mysqld-auto.cnf(json格式),mysql服务器在重启时会读取这个文件

mysql> set persist password_history=6
mysql> show variables like 'password%';
#cat /var/lib/mysql/mysqld-auto.cnf
{ "Version" : 1 , "mysql_server" : { "password_history" : { "Value" : "6" , "Metadata" : { "Timestamp" : 1582708858483578 , "User" : "root" , "Host" : "localhost" } } } }

在之前mysql版本中如果给运行中mysql修改参数只能在当前mysql进程中设置,但是mysql重启后就会失效;如果写入配置文件my.cnf里则需要重启服务,这两种方法都不太方便。

针对用户修改

mysql> alter user 'test'@'%' password history 10;
mysql> select User,Host,Password_reuse_history from mysql.user;
设置成功后测试,发现密码不能修改并报错
mysql> alter user 'test'@'%' identified by 'Cloudbu@123';
ERROR 1396 (HY000): Operation ALTER USER failed for 'test\'%'@'%'

(4)角色管理
mysql8.0提供角色管理的新功能,角色是一组权限的集合
步骤:
1.先创建角色
2.给这个角色赋予实现定义好的权限
3.把角色授权给某个用户

创建一个数据库
mysql> create database roleDB;
创建一张表
mysql> create table roleDB.table_auth(id int);
创建一个角色
mysql> create role 'write_role';
查看用户信息表
mysql> select host,user,authentication_string from mysql.user where user="write_role";
+------+------------+-----------------------+
| host | user       | authentication_string |
+------+------------+-----------------------+
| %    | write_role |                       |
+------+------------+-----------------------+
1 row in set (0.00 sec)
#这里write_role是一个没有密码的用户,可以看出mysql是用用户来模拟角色的
授权,授予roleDB库上的增删改查权限
mysql> grant select,insert,update,delete on roleDB.* to 'write_role'; 
创建用户并赋予密码
mysql> create user 'yonhu_role1' identified by '@Password123';
将角色授予用户
mysql> grant 'write_role' to 'yonhu_role1';

mysql> show grants for 'yonhu_role1';
mysql> show grants for 'yonhu_role1' using 'write_role';

用yonhu_role1用户登录
[root@nfs01 ~]# mysql -uyonhu_role1 -p
mysql> select user();
设置角色(必须设置)
mysql> set role 'write_role'; 
查看当前角色
mysql> select current_role();
+------------------+
| current_role()   |
+------------------+
| `write_role`@`%` |
+------------------+
mysql> select * from roleDB.table_auth;
Empty set (0.01 sec)
为每个用户设置默认角色
[root@nfs01 ~]# mysql -uroot -p
mysql> set default role 'write_role' to 'yonhu_role1';
查看用户角色信息,这个是mysql8新增加的表,用户锁设计到角色的信息
mysql> select * from mysql.default_roles;
+------+-------------+-------------------+-------------------+
| HOST | USER        | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+------+-------------+-------------------+-------------------+
| %    | yonhu_role1 | %                 | write_role        |
+------+-------------+-------------------+-------------------+
撤销角色
mysql> revoke insert,update,delete on roleDB.* from 'write_role';
mysql> show grants for 'write_role';
mysql> show grants for yonhu_role1;

MySQL权限表

8.2.2 MySQL权限表

mysql.user Global level
用户字段、权限字段、安全字段、资源控制字段
mysql.db、mysql.host Database level
用户字段、权限字段
mysql.tables_priv Table level
mysql.columns_priv Column level
mysql.procs_mysql.user Global level
用户字段、权限字段、安全字段、资源控制字段
mysql.db、mysql.host Database level
用户字段、权限字段
mysql.tables_priv Table level
mysql.columns_priv Column level
mysql.procs_priv

mysql8 用户管理

MySQL用户管理

登录和退出MySQL

[root@nfs01 ~]# mysql -h 192.168.5.240 -P 3306 -u root -p123 -e 'select user,host from mysql.user'
退出:
mysql> \q
mysql> exit
mysql> quit

创建用户

创建用户并授权

mysql> create user 'test01'@'localhost' identified by 'Cloudbu@123';
mysql> grant all on *.* to 'test01'@'localhost' with grant option;

带过期时间用户的创建

mysql> create user 'test02'@'192.168.42.%' identified by 'Cloudbu@123' password expire interval 90 day;
mysql> grant all on *.* to 'test02'@'192.168.42.%' with grant option;

修改已创建用户密码的过期时间

方法一:修改主配置文件
/etc/my.conf
方法二:设置全局策略
mysql> set persist default_password_lifetime = 180;

给特定用户设置密码过期时间
mysql> alter user 'test01'@'localhost' password expire interval 90 day;
禁用过期密码策略

mysql> create user 'test02'@'localhost' password expire never;
mysql> alter user 'test02'@'localhost' password expire never;

引用密码默认策略

mysql> create user 'test04'@'localhost' password expire default;
mysql> alter user 'test04'@'localhost' password expire default;

INSERT语句创建用户(该方法创建的用户没有密码,需要改密后登陆)

mysql> INSERT INTO mysql.user(User,Host,ssl_cipher,x509_issuer,x509_subject)
values('user2','localhost','','','');
FLUSH PRIVILEGES;
[root@localhost ~]# mysqladmin -uuser2 password 'Cloudbu@123'
[root@localhost ~]# mysql -uuser2 -p

删除用户

方法一:DROP USER语句删除
mysql> drop user 'user2'@'localhost';
方法二:DELETE语句删除
mysql> DELETE FROM mysql.user where User='admin' and Host='192.168.42.175';

修改用户密码

root修改自己密码

方法一
mysqladmin -uroot -p123 password 'new_password'

方法二

mysql> flush privileges;
mysql> alter user 'root'@'%' identified with mysql_native_password by
"ABC123.com";
mysql> flush privileges;

方法三(不建议使用)
直接修改 update user set authentication_string='ABC123.com' where user='root';

root修改其他用户密码

方法一

mysql> use mysql
mysql> ALTER USER 'test04'@'localhost' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'ABC123.com';

方法二

mysql> use mysql
mysql> set password for 'test04'@'localhost' = 'Cloudbu@123';
mysql> flush privileges;
普通用户修改自己密码

mysqladmin -uzhuzhu -p123 password 'new_password'

修改客户端用户

mysql> use mysql;
mysql> create user 'anliu02'@'localhost' identified by 'Cloudbu@123';
mysql> update user set host='%' where user='anliu02';
mysql> flush privileges;

MySQL8权限管理

应用顺序

user (Y|N) ==> db ==> tables_priv ==> columns_priv

用户授权

grant 权限列表 on 库名.表名 to 用户名@'客户端主机' [identified by '密码' with
option参数];
==权限列表 all 所有权限(不包括授权权限)
select,update
==数据库.表名
*.* 				所有库下的所有表 Global level
web.*				库下的所有表 Database level
web.stu_info web	库下的stu_info表 Table level
==客户端主机 % 所有主机
192.168.2.% 	192.168.2.0网段的所有主机
192.168.2.168 	指定主机
localhost 		指定主机

with_option参数

 GRANT OPTION: 授权选项
 MAX_QUERIES_PER_HOUR: 定义每小时允许执行的查询数
 MAX_UPDATES_PER_HOUR: 定义每小时允许执行的更新数
 MAX_CONNECTIONS_PER_HOUR: 定义每小时可以建立的连接数
 MAX_USER_CONNECTIONS: 定义单个用户同时可以建立的连接数

grant示例

mysql> create user 'abliu'@'%' identified by 'Cloudbu@123';
mysql> grant select,insert,update,delete on school.* to abliu@'%';
mysql> create user 'anliu01'@'localhost' identified by 'Cloudbu@123';
mysql> grant ALL on school.* to 'anliu01'@'localhost';
mysql> grant select on student.* to 'anliu01'@'localhost';
mysql> grant select(Sno),insert(Sname,Ssex) on xingyun.Student to 'anliu01'@'localhost';
mysql> grant all on test.* to 'anliu01'@'localhost';
mysql> alter user 'anliu01'@'localhost' with MAX_QUERIES_PER_HOUR 90;

权限查看

SHOW GRANTS\G #查看当前用户
SHOW GRANTS FOR admin1@'%'\G #查看指定用户

权限回收

语法:

REVOKE 权限列表 ON 数据库名 FROM 用户名@‘客户端主机’

示例

REVOKE DELETE ON *.* FROM admin1@’%’; #回收部分权限
REVOKE ALL PRIVILEGES ON *.* FROM admin2@’%’; #回收所有权限

例如

mysql> revoke all privileges,grant option from abliu;
mysql> revoke select on school.* from 'anliu01'@'localhost';

请关注公众号获取更多资料

发表评论