一、如何在给定场景下为用户授权
1、MySQL常用的用户权限
(1)DML权限
权限 | 备注 |
---|---|
select | 查询表中数据 |
insert | 向表中插入数据 |
update | 更新表中数据 |
delete | 删除表中数据 |
execute | 执行存储过程 |
(2)DDL权限
权限 | 备注 |
---|---|
create | 新建数据库、数据表 |
alter | 修改表结构 |
drop | 删除数据库、数据表 |
index | 建立和删除索引 |
(3)Admin权限
权限 | 备注 |
---|---|
create user | 建立新的用户 |
grant option | 为其他用户授权 |
super | 管理服务器,比如设置全局变量、kill掉进程、执行change master语句等 |
一般来说,Admin权限只有DBA使用
(4)查看当前MySQL所有的权限列表
show privileges;
mysql> show privileges;
+----------------------------+---------------------------------------+-------------------------------------------------------+
| Privilege | Context | Comment |
+----------------------------+---------------------------------------+-------------------------------------------------------+
| Alter | Tables | To alter the table |
| Alter routine | Functions,Procedures | To alter or drop stored functions/procedures |
| Create | Databases,Tables,Indexes | To create new databases and tables |
| Create routine | Databases | To use CREATE FUNCTION/PROCEDURE |
| Create role | Server Admin | To create new roles |
| Create temporary tables | Databases | To use CREATE TEMPORARY TABLE |
| Create view | Tables | To create new views |
| Create user | Server Admin | To create new users |
| Delete | Tables | To delete existing rows |
| Drop | Databases,Tables | To drop databases, tables, and views |
| Drop role | Server Admin | To drop roles
...
2、如何为用户授权
grant \
# 指定授予用户什么权限
select,insert,update,delete on \
# 指定这些权限可以操作哪些数据库,哪些数据表
db.tb \
# To关键字
to \
# 指定为哪个用户授权
user@ip
注:@ip如果省略,则默认为%效果,即外部任何网络均可访问。
这里还可以是@localhost、@192.168.78.% 这种指定仅本地服务器可以访问、仅指定网段可以访问。
一次只能为用户授权一个数据库的权限,如果想为用户授予多个数据库权限,则需要执行多次授权语句。这点在下面的使用实例中会体现。
3、如何收回用户权限
revoke \
# 回收的权限列表
insert,update \
# 指定收回哪些数据库、数据表的操作权限
on db.tb \
# From关键字
from \
# 指定收回哪个用户的权限
user@ip
4、使用实例
(1)5.5,5.6,5.7版本,如何为用户授权
# 创建用户
mysql> create user 'test_user'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
# 为用户授予在new_retail和public数据库的所有数据表的select、update、insert权限
mysql> grant select,update,insert on new_retail.* to 'test_user';
Query OK, 0 rows affected (0.00 sec)
mysql> grant select,update,insert on public.* to 'test_user';
Query OK, 0 rows affected (0.00 sec)
#查看用户当前拥有的权限
mysql> show grants for 'test_user';
+-------------------------------------------------------------------+
| Grants for test_user@% |
+-------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test_user`@`%` |
| GRANT SELECT, INSERT, UPDATE ON `public`.* TO `test_user`@`%` |
| GRANT SELECT, INSERT, UPDATE ON `new_retail`.* TO `test_user`@`%` |
+-------------------------------------------------------------------+
3 rows in set (0.00 sec)
(2)8.0版本中如何为用户授权
8.0版本之前,还没有角色的概念,因此只能对单个用户逐一授权。
但8.0版本之后,新增了角色的概念,我们可以先创建角色,然后为角色分配权限,最后再给用户分配角色。
当然,我们也可以采用和之前5.7版本一样的方式,不引入角色的概念,直接为用户授权。
下面演示8.0版本中,如何使用角色,为用户授权
# 创建角色
mysql> create role 'test_role';
Query OK, 0 rows affected (0.00 sec)
# 给角色授予权限
mysql> grant select on *.* to test_role;
Query OK, 0 rows affected (0.01 sec)
# 创建用户
mysql> create user 'read_user'@'%' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
# 给用户赋予角色
mysql> grant 'test_role' to 'read_user';
Query OK, 0 rows affected (0.00 sec)
# 给角色增加insert权限
mysql> grant insert on *.* to 'test_role';
Query OK, 0 rows affected (0.00 sec)
# 移除角色insert权限
mysql> revoke insert on *.* from 'test_role';
Query OK, 0 rows affected (0.01 sec)
# 查看角色与用户关系
mysql>select *from mysql.role_edges;
+-----------+-----------+---------+-----------+-------------------+
|FROM_HOST|FROM_USER|TO_HOST|TO_USER |WITH_ADMIN_OPTION|
+-----------+-----------+---------+-----------+-------------------+
|% |role_test |% |read_user |N |
+-----------+-----------+---------+-----------+-------------------+
1row inset (0.00sec)
# 查看用户当前拥有的角色
mysql> show grants for 'read_user';
+------------------------------------------------------------+
| Grants for read_user@% |
+------------------------------------------------------------+
| GRANT USAGE ON *.* TO `read_user`@`%` |
| GRANT `insert_role`@`%`,`test_role`@`%` TO `read_user`@`%` |
+------------------------------------------------------------+
# 删除角色
mysql>drop role test_role;
QueryOK, 0rows affected (0.06sec)
二、如何加强数据库账号的安全
对于这一点,主要需要保证以下几点:
1、最小权限原则
2、密码强度策略
3、密码过期原则(指定PASSWORD EXPIRE参数)
4、限制历史密码重用原则(8.0版本专属,ASSWORD REUSE INTERVAL参数)
5、要求gitlab、github上传代码时,.env等账号配置文件不得同时上传
三、如何迁移数据库账号到新服务器
1、源数据库与目的数据库版本一致
备份mysql库,在目的实例恢复mysql库
2、源数据库与目的数据库版本不一致
当源数据库与目的数据库版本不一致时,有两种方式来备份数据库账号,分别实例演示。
(2.1)使用MySQL自带工具MySQLPump【推荐】
# 在Linux主机执行
mysqlpump -uroot -p --users --exclude-databases=sys,mysql,public,test_80,new_retail > user.sql
说明:该方式支持5.7.11之后的版本,包括8.0版本
(2.2)使用pecona-toolkit里的pt-show-grants工具获取数据库所有授权语句,然后在目的数据库中执行这些SQL。
如何导出实例:
[root@v2 ~]# pt-show-grants u=root,p=123456,h=192.168.78.102,P=3307
-- Grants dumped by pt-show-grants
-- Dumped from server 192.168.78.102 via TCP/IP, MySQL 5.6.51 at 2021-08-18 05:57:28
-- Grants for 'root'@'%'
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION;
-- Grants for 'root'@'localhost'
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION;
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION;
[root@v2 ~]#
注意,pt-show-grants 当前暂不支持获取8.0版本的授权SQL,仅支持5.5,5.6,5.7版本,当然这也足够了,因为我们迁移数据库大多都是同版本迁移或升级,没有降级一说的。