MySQL 账号和权限管理笔记整理
99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式
写在前面
- 博文内容极客时间老师的专栏学习笔记整理:
- https://time.geekbang.org/column/article/802420
- 理解不足小伙伴帮忙指正 :),生活加油
99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式
账号和权限管理
在MySQL数据库中,账号和权限管理是非常重要的部分,它确保了数据库的安全性和数据的完整性。
在 mysql 中一个用户由两部分组成,username
是用户名,host
是允许登录数据库的客户端的主机名或 IP。host
中可以使用通配符,使用百分号 “%” 匹配任意字符串,使用下划线 “_” 匹配一个字符
1 | create user 'username'@'host' identified by 'complex_password'; |
同名用户条目的优先级
MySQL 允许创建 username
相同,但 host
不同的用户。
1 | create user 'u03'@'%' identified by 'somepassword'; |
可以通过 mysql.user
来查看创建的用户数据
1 | mysql> select user,host from mysql.user where user='u03'; |
登录数据库之后,可以用函数 current_user
来获取当前的登录用户
1 | # mysql -u u03 -psomepassword -h172.16.121.234 |
或者用 show grants
命令也能看到当前的登录用户
1 | mysql> show grants; |
在登陆的时候,MySQL 会把所有的用户记录
按优先级从高到低
的顺序排列,缓存到内存里。服务端接收到客户端发起的连接请求后,从请求包中解析出用户名和密码信息
mysql.user
表中用户条目的优先级如何确定呢?基本的规则是这样的:
- IP 条目的优先级最高。IP 条目中没有通配符,精确的 IP 和 IP 地址段都是 IP 条目。
- 精确 IP 的优先级比 IP 地址段的优先级高。
- 对于 2 个 IP 地址段,前缀长的优先级更高。比如
172.16.121.0/24
优先级比172.16.0.0/16
高。 - 不使用通配符的条目比使用通配符的条目优先级高。
- 对于都使用了通配符的条目,则根据第一个通配符在 host 字段中出现的位置来判断优先级。通配符出现的位置越靠前,优先级越低。比如 ‘%’ 的优先级最低,’abc%’ 的优先级比 ‘abcd%’ 低。
1 | 'u03'@'172.16.121.237' |
在真实环境中,我们经常会设置 skip_name_resolve
,这样 MySQL 就只会根据 IP
来验证用户,不需要再将 IP
反解析成主机名。
1 | ## my.cnf |
密码验证组件
不要给 MySQL 用户设置过于简单的密码,可以通过密码验证组件来强制密码的复杂度。
使用 RPM
安装的 MySQL 默认就已经开启了密码验证组件。
如果你使用了二进制安装,可以用命令 INSTALL COMPONENT
来启用密码验证。
1 | mysql> INSTALL COMPONENT 'file://component_validate_password'; |
无法创建密码过于简单的用户,报错提示
1 | mysql> create user 'ux'@'%' identified by 'simplepassword'; |
1 | mysql> create user 'ux'@'%' identified by 'Complex-Password-2024'; |
密码验证组件有几个参数可以配置,你可以根据自己的需求适当调整这些参数。
1 | mysql> show variables like 'validate_password%'; |
权限管理
早期版本中,如果被授权的用户不存在,那么在执行 grant
语句时,会自动创建这个用户。
在 MySQL 5.7
中,SQL_MODE
中加入了 NO_AUTO_CREATE_USER
选项,用来避免这种 grant
语句自动创建用户的行为。
到了 MySQL 8.0
,已经不再支持 NO_AUTO_CREATE_USER
选项了。
1 | grant privileges |
执行 grant
时,被授权的用户必须已经存在,否则会报错。
1 | mysql> grant select on *.* to 'readonly'@'%'; |
在 MySQL 中,有的权限是全局
的,这些权限跟某个具体的数据库
没有关系,授权时需要使用 on *.*
1 | grant process on *.* to 'u03'@'%'; |
比如这个例子给用户 u03
授权了查看 process
列表的权限。
有的权限跟数据库或数据库中的对象相关,授权时可以指定具体的数据库或数据库对象。下面这个 grant
语句给用户 u03
授权了数据库 db01
的 DDL
权限。
1 | grant create,index,alter,drop on db01.* to 'u03'@'%'; |
授权后,u03
可以创建库名为 db01
的数据库,并在这个库中创建表、修改表结构、DROP 表,但是不能读写
表中的数据。
1 | mysql> show grants; |
可以创建表,修改表结构,DROP表,但是不能读写表中的数据
1 | ## 可以创建表,修改表结构,DROP表,但是不能读写表中的数据 |
不能读写表数据
1 | mysql> insert into t1 values(1,2,3); |
需要给账号添加相应的权限后,才能访问表中的数据。
1 | mysql> grant select,insert,update,delete on db01.* to 'u03'@'%'; |
grant
语句中,授权对象(库名和对象名)也可以使用通配符,使用 "%"
匹配任意字符,使用 "_"
匹配一个字符。
1 | grant create,drop,alter,index on `db__`.* to 'u03'@'%'; |
授权后,u03
用户可以创建库名以 db
开头,并且库名长度是 4
个字节的数据库。
1 | mysql> create database db_1; |
如果库名中有下划线 "*"
,可以在 grant
时使用转义符对通配符 "*"
进行转义。下面的 SQL
把 db_1
库的读写权限赋给了 u03
用户
1 | mysql> grant select,insert,update,delete on `db\_1`.* to 'u03'@'%'; |
使用 show grants
命令查看 u03
用户当前的权限
1 | mysql> show grants; |
最小权限原则
最小权限原则管理数据库用户的权限时,要遵循最小权限原则。
root 用户要交给少数管理人员管理,其他任何人不能使用 root 用户。有的公司出于安全考虑,还会删除系统自带的 root 用户,并单独创建一个超级管理员用户。给不同的业务方分配不同的用户,并按业务的实际需求授予最小的权限。
举例来说,如果业务
方的需求是同步数据库中的数据,只需要对库表授予 SELECT 权限。对于一般的应用程序,需要读写数据,授予 SELECT、INSERT、UPDATE、DELETE、EXECUTE
这些权限就可以了。
对于 DBA 或运维
人员,需要执行数据库变更,可以授予CREATE、ALTER、DROP、INDEX 等 DDL
权限,以及 PROCESS、SUPER
等管理权限
开发环境和生产环境的用户,不要使用相同的密码。不同的业务方共用同一个用户、授予用户超出需要的权限、开发环境和生产环境使用相同的用户名和密码,都会给数据库安全带来极大的风险
。
有时候为了方便,你可能会把all privileges
授予一个用户,然后所有业务方都使用这个用户来访问数据库。这是非常危险的,千万不要这么做。
博文部分内容参考
© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 :)
https://time.geekbang.org/column/article/802420
© 2018-至今 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)
MySQL 账号和权限管理笔记整理
https://liruilongs.github.io/2024/12/04/待发布/MySQL 账号和权限管理笔记整理/