TDSQL案例:账户加固会影响到视图无法访问?
背景
用户反馈实例视图无法访问,与用户沟通后,了解到近期安全变更将部分用户绑定的ip从%变为客户端ip地址,发生故障后,用户紧急进行了回滚,视图访问恢复正常,业务恢复。
分析
首先mysql族的关系数据库,账户组成由user@ip共同决定,对其中任意结构的变更都将破坏原来账户的定义。 针对于用户的描述,包括关键行为:1、删除账户(变更相当于删除之前的账户);2、视图无法使用;3、修复账户后又恢复。我们估计是视图的definer被删除导致,查看用户故障视图,果然发现其定义者就是被删除的用户。换一种说话,由于视图definer(由user@ip组成)在mysql.user表中被移除,导致该视图无法正常提供访问。
### https://mariadb.com/kb/en/create-view/
If you specify the DEFINER clause, these rules determine the legal DEFINER user values:
If you do not have the SUPER privilege, the only legal user value is your own account, either specified literally or by using CURRENT_USER. You cannot set the definer to some other account.
If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.
If the SQL SECURITY value is DEFINER but the definer account does not exist when the view is referenced, an error occurs.
其流程图可以展示为:
扩展
我们以一个测试的mariadb视图创建语句来做分析
MariaDB [alan]> show create view aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`%` SQL SECURITY DEFINER VIEW `aaa` AS select `alan`.`ha`.`id` AS `id`,`alan`.`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set, 1 warning (0.00 sec)
其中view列的意义是视图的名称,character_set_client列和collation_connection列为视图使用到的字符集和排序规则; create view当中包含了视图的主体结构,分类列举: 1、ALGORITHM=UNDEFINED ALGORITHM表示实例对视图的处理算法,这个参数有三个值,包括MERGE、TEMPTABLE以及缺省值UNDEFINED,其中merge可以简单的理解为将外部的sql语句和视图定义的语句合并起来,到原表进行查询;TEMPTABLE与merge相对应,他将视图中的结果先储存到临时表,外部sql直接调用临时表中的结果;至于UNDEFINED,可以理解为实例按照场景自己决定使用哪一个处理算法。 2、DEFINER=`vky`@`%` DEFINER表示视图的定义者(包括用户名以及绑定的ip),通常可以显式的指定,缺省值为当前用户,也就是select current_user();返回的用户。 3、SQL SECURITY DEFINER SQL SECURITY约束视图的安全性策略,他的值有DEFINER和INVOKER。其中DEFINER的策略为如果引用者存有引用该视图的权限(该视图的select权限),通常可以成功返回结果;如果为INVOKER,他需要引用视图的账户也需要同时对视图中的原表具有select的权限,否则也会返回报错。
回到我们故障场景,用户修改了视图定义者的host之后,导致视图无法访问,这里我们前面也进行了充分的解释,更进一步,既然不能破坏user@host这个结构,那我们破坏掉这个用户的权限从而来实现软删除的目的可以不呢?我们对SQL SECURITY 解释中,默认definer策略下,当前账户只需要有试图的select权限即可以正常的引用,其中对原表数据访问实际上使用到了定义者的权限,如果我们对定义者的权限进行完全破坏,实际上也是会失去对视图的使用。以下截屏是我们测试的结果:
MariaDB [alan]> show grants for vky@'%';
+--------------------------------------------------------------------------------------------------------+
| Grants for vky@% |
+--------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'vky'@'%' IDENTIFIED BY PASSWORD '*96A12F0614169E80CC46E92BDE3DBF0FD4751D7C' |
+--------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [alan]> select * from aaa;
ERROR 1356 (HY000): View 'alan.aaa' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
MariaDB [alan]> show grants for vky@'%'G
*************************** 1. row ***************************
Grants for vky@%: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON *.* TO 'vky'@'%' IDENTIFIED BY PASSWORD '*96A12F0614169E80CC46E92BDE3DBF0FD4751D7C'
1 row in set (0.00 sec)
MariaDB [alan]> select * from aaa;
+----+------+
| id | name |
+----+------+
| 1 | alan |
| 2 | joke |
| 3 | tom |
+----+------+
3 rows in set (0.00 sec)
同样的逻辑,在invoker策略下,虽然删除定义者不会影响其它拥有权限的用户引用视图,但是这里也跑偏了创建视图的初衷。
那要如何完成变更definer操作呢?
由于云上实例通常不存在super权限,所以无法直接使用super账户直接将视图从a归属到b名下,但是却可以使用b账户登录实例,对视图进行definer的变更操作。如截屏:
MariaDB [alan]> show create table aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
MariaDB [alan]> alter ALGORITHM=UNDEFINED DEFINER=`vky`@`10.%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`;
Query OK, 0 rows affected (0.00 sec)
MariaDB [alan]> show create table aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`10.%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
MariaDB [alan]> select current_user();
+----------------+
| current_user() |
+----------------+
| vky@10.% |
+----------------+
1 row in set (0.00 sec)
MariaDB [alan]>
该操作完成之后,,用户方可进行对高风险用户(绑定%的用户)进行回收操作。
- $.each()与$(selector).each()区别详解
- javascript typeof
- php中json_encode
- Java高级进阶:自定义ClassLoader
- 字符串拼接+和concat的区别
- Spring Boot Runner启动器
- Spring Boot自动配置原理、实战
- Spring Aware容器感知技术
- 深入探究frame和bounds的区别以及setbounds使用
- 如何生成二维码过程详解
- hashCode和identityHashCode的区别你知道吗?
- SpringCloud注册中心高可用搭建
- SpringMVC表单验证器的使用
- Hadoop作业提交与执行源码分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Ubuntu20.04安装搜狗输入法的详细步骤
- linux系统安装msf的过程详解
- Linux删除系统自带版本Python过程详解
- Linux时间子系统之时间的表示示例详解
- 如何在Linux中修改tomcat端口号
- centos7修改系统语言为简体中文的实现
- Linux 通过Rsync+Inotify实现本、异地远程数据实时同步功能
- linux实现猜数字小游戏源码
- linux编译kernel和svn版本冲突的解决办法
- 在 Ubuntu Linux 上安装 Oracle Java 14的方法
- 在 Linux 系统中手动滚动日志的方法
- Linux进程管理工具supervisor安装配置教程
- Linux执行可执行文件提示No such file or directory的解决方法
- 详解bash中的脚本调试机制
- 在 Linux 上查看和配置密码时效的方法