此专题题目较多,因此分为上下两部分来讲,此为上篇。
完整版题库请到我的资源中下载,此为传送门。 https://download.csdn.net/download/kanon_lgt/85010419?spm=1001.2014.3001.5503
讲解:
在mysql登录认证体系中,有两种登录权限认证机制,如下:
1、mysql自身的登录认证模块。--社区版与企业版都有
mysql通过mysql server与mysql client自身就可完成身份验证,具体有如下三种:
- mysql_native_password
- sha256_password
- caching_sha2_password
2、插件式认证接口模块。--企业版独有
mysql借用外部用户权限管理系统完成登录验证,而不需要mysql自身验证模块
具体有如下四种典型代表:
- PAM(Pluggable Authentication Modules)--可以使用linux本地OS用户或者LDAP来完成用户验证。
- WPA(Windows Pluggable Authentication) --可以使用windows 的OS权限系统完成用户验证。
- LDAP Authentication --可以使用LDAP完成用户验证。
- LDAP SASL(Simple Authenticaion and Security Layer) --更安全的LDAP,密文传输。
而以上四种插件式认证模块中,PAM、LDAP、WPA都需要mysql client以明文(plaintext/cleartext)方式发送密码,LDAP SASL是为了更安全的传输数据而增加了加密和安全层模块,因此是以密文方式发送密码。
补充:
插件式认证接口,是如何让mysql能够完美兼容这些外部认证系统的呢?其实是因为在mysql client的libmysqlclient.so中,实现了对PAM、WPA、LDAP、LDAP SASL等系统的接口兼容,通过它来实现的适配,它被静态编译到了mysql cient中作为客户端插件使用,具体匹配关系如下:
认证方式 | 客户端插件 | 服务器端插件 |
PAM | mysql_clear_password | authentication_pam |
Simple LDAP | mysql_clear_password | authentication_ldap_simple |
WPA | authentication_windows_client | authentication_windows |
LADP SASL | authentication_ldap_sasl_client | authentication_ldap_sasl |
看题目:
题目中提问的是服务器端认证插件需要接收客户端明文的认证方式是哪两种。
看选项:
选项A和D,LDAP和PAM,正如上面所讲,都需要mysql client plugin 发送明文到服务器端。
选项B和F,mysql_native_password和sha256_password,作为mysql自身的认证插件,都是需要客户端发送hash和加密后的数据到服务器端的。
选项C,windows native authentication与windows pluggable authentication是不一样的,前者是加密的,而后者是明文的。
选项F,LDAP SASL与Simple LDAP不同,前者是加密的,而后者是明文的。
因此,选项AD正确。
讲解:
没什么可说的,直接看选项
选项B,将mysql server置于防火墙后方
选项E,只允许应用服务器建立mysql 连接
因此,选项BE正确。
讲解:
1、连接控制插件有什么用呢?
用来给前端连接数据库的行为指定规则。比如:
- 前端连接数据库失败到限制次数后则延迟该账号登录时间
- 记录前端连接数据库的失败情况
2、连接控制插件有如下两个:
- connection-control plugin
- connection_control_failed_login_attempts
此插件位于$BASEDIR/lib/plugins目录下connection_control.so。
3、连接控制插件作用是:
- connection_control:用来控制登录失败的次数以及失败到限制次数后延迟响应的时间。
- connection_control_failed_login_attempts:用来将登录失败的操作记录到information_schema库中
4、连接控制插件安装命令为:
INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so'; INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
5、连接控制插件关键全局变量:
- connection_control_failed_connections_threshold --限制连续登陆失败次数,默认值为3,超过次数将延迟对登录请求进行延迟响应。
- connection_control_max_connection_delay -- 最大延迟响应时间,单位毫秒。
- connection_control_min_connection_delay -- 最小延迟响应时间,单位毫秒。
6、参数设置规则:
connection_control_max_connection_delay 必须大于等于connection_control_min_connection_delay
7、使用举例:
假如系统设置变量如下:
- connection_control_failed_connections_threshold=3
- connection_control_min_connection_delay=1000
- connection_control_max_connection_delay=200000
那么当一个用户连续登录3次都失败的情况下,第四次登录请求将被挂起延迟1000毫秒,若继续失败,第五次登录的延迟时间将继续增加,以此类推,如果一直失败,则会最大延迟200000毫秒。
8、连接控制插件有什么意义呢?
- 防止DDos或者持续暴力连接攻击。对保护数据库安全有很大的意义。
看题目:
题目给出了如下参数设置:
connection_control_min_connection_delay=1000,connection_control_max_connection_delay=2000,
此时将connection_control_min_connection_delay设置为3000,则违反了connection_control_min_connection_delay不能大于connection_control_max_connection_delay的规则,因此会直接报错。
正确的设置方法是先将connection_control_max_connection_delay设置为5000,再将connection_control_min_connection_delay设置为3000.
因此,选项D正确。
讲解:
role的概念是mysql8.0开始加入的,在之前是用proxy-user来实现的。
role是一组权限的集合,有如下操作可以使用:
- create role / drop role
- grant role / revoke role
- set default role
- mandatory_roles 和 activate_all_roles_on_login
重点要讲的是 mandatory_roles:
1、mandatory_roles是什么
它是强制赋予给全部users的roles集合,当系统中设置了mandatory_roles,那么所有的已经存在的users都讲自动获得这些roles,每次新创建的user也会立刻获得这些roles,并且不会被revoke方式撤销。
2、mandatory_roles设置方式
SET PERSIST mandatory_roles = '`role1`@`%`,`role2`,role3,role4@localhost';
3、mandatory_roles有什么规则
- mandatory_roles列表中的roles不能通过drop role方式删除,
- mandatory_roles列表中的roles不会出现在mysql.role_edges中,
- mysql.role_edges列表中的roles可以通过show grants 看到。
看选项:
选项A,当drop role的时候,如果这个role不存在,则会报错。正确。
选项F,当drop role的时候,如果这个role在mandatory_roles列表中,则会报错。正确。
选项BCD,都说了同一个事情,就是drop role之前要revoke全部权限集合或者删除对应的user,又或者从所有的user上revoke这些role。这都是错误的。没必要这么做,它们会被直接drop,其对应的user将立刻失去这些role,即使已经连接上来的session对应的user也会立刻失去这些role。
选项E,需要ADMIN OPTION才能drop role,这是错误的。并不需要。
因此,选项AF正确。
讲解:
data-at-rest:即静态数据。
TDE:transparent data encryption,是mysql提供的对InnoDB静态数据加密的功能,它支持加密如下数据:
- file-per-table tablespaces,
- general tablespaces,
- the mysql system tablespace,
- redo logs,
- undo logs.
操作举例:
- 对已经存在的file-per-table tablspace加密:
ALTER TABLE t1 ENCRYPTION = 'Y';
- 对新创建的file-per-table tablespace加密:
CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';
- 对已经存在的tablespace加密:
ALTER TABLESPACE ts1 ENCRYPTION = 'Y';
- 对新创建的tablespace加密:
CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' ENCRYPTION = 'Y' Engine=InnoDB;
- 对系统表空间mysql tablespace加密:
ALTER TABLESPACE mysql ENCRYPTION = 'Y';
看题目:
对一个已经存在的InnoDB表进行TDE加密
看选项:
只有A选项能实现题目要求
因此,选项A正确。
讲解:
mysql proxy user是mysql 5.7的模拟role的实现,一个proxy user可以理解为一个role,它具有一些权限的集合;
在mysql 8.0版本中已经实现了role功能。
此题出的非常狡猾,本来正常的proxy user结构逻辑都是非常清晰简明的。然而此题却用了匿名用户来作proxy user,这就要仔细分析推理了。
首先,看下正常的proxy user是如何做的,举个最简单的例子:
1、创建一个proxied user,也就是role:
CREATE USER 'employee'@'localhost' IDENTIFIED WITH mysql_no_login; --不允许直接登录 GRANT ALL ON employees.* TO 'employee'@'localhost';
2、创建一个proxy user,也就是user,它将从proxied user处获得权限:
CREATE USER 'employee_laoge'@'localhost' IDENTIFIED WITH sha256_password BY 'LaoGeDB123!';
3、把employee代理给employee_laoge:
GRANT PROXY ON 'employee'@'localhost' TO 'employee_laoge'@'localhost';
4、用employee_laoge登录数据库
msyql -uemployee_laoge -p
5、查看下现在的用户
mysql> select user(),current_user(),@@proxy_user; +--------------------------+--------------------+------------------------------+ | user() | current_user() | @@proxy_user | +--------------------------+--------------------+------------------------------+ | employee_laoge@localhost | employee@localhost | 'employee_laoge'@'localhost' | +--------------------------+--------------------+------------------------------+
6、结论很清晰:
- user()---真实登录用户,proxy user;
- current_user()---被proxy用户,也就是proxied user,或者说是role;
- @@proxy_user---真是登录用户,proxy user;
其次,看下题目中是怎么作的:
题目中给出的如下:
- user()---jsmith@localhost;
- current_user()---accounting@localhost;
- @@proxy_user---''@'%';--一个匿名用户;
我在实验环境中做过多个测试,都没有复现出题目中的内容。
所以,此题我也搞不明白,暂时无解。根据自己喜欢,选个E吧。
讲解:
UPDATE权限不包含SELECT权限,因此对一个表的列具有UPDATE权限,不代表有SELECT权限。
在一个表上做对某个列的WHERE过滤、ORDER BY、GROUP BY、CONCAT、MAX、MIN等都需要SELECT权限。
看题目:
jsmith对表world.country的name列有update权限,因此她可以对此列做update,但仅限于update,不能对此列做过滤。
看选项:
选项A,对name列作更新,且只更新limit 1,第一行。并未涉及到对此列的SELECT。
选项B,WHERE name='old',需要SELECT权限。
选项C,ORDER BY name, 需要SELECT权限。
选项D,CONCAT('New',Name),需要SELECT权限。
选项E,UPDATE全部记录的Name字段,并未涉及到对此列的SELECT。
因此,选项AE正确。
讲解:
mysql的audit log events,审计日志事件是存放在file中的,并不存在table中,所以mysql库中是看不到它的。
而当你在mysql库中看到audit_log的表时,这个表中存储的并不是audit log events,而是审计规则。
这个是此题比较狡猾的地方,表面看是考mysql 元数据表空间的内容,实际是考audit log events的存储方式。
要看mysql 系统库中都有什么表,执行show tables即可看到。
看选项:
选项A,performance monitoring information,性能监控信息,存储在performance_schema中。
选项BFG,plugins、help_topics、time_zone都存储在mysql库中。
选项C,audit log events,存储在file中。
选项D,rollback segments,存储在undo表空间中。
选项E,information about table structures,表结构信息,5.7版本中存储在mysql中; 8.0版本开始,表结构信息,也就是表定义直接存储在表的ibd文件头中,不再保留单独的结构文件.frm。
因此,选项BFG正确。
讲解:
首先,要明白两个基础:
- datafile存放于datadir
- mysqld-auto.cnf存放于datadir(mysqld-auto.cnf是SET PERSIST生成的)
看题目:
datadir目录权限被递归修改为777(world read/write/execute)后,受影响的文件都有什么。
看选项:
选项A,datafiles在datadir下,777使其可以被任何用户删除。
选项B,用户可以修改甚至覆盖mysql的配置文件。如果有mysqld-auto.cnf,是可以这样的。
选项C,SQL 注入可以被用来插入破坏数据到数据库中。这个跟datadir权限无关。
选项D,mysql启动需要花费更多的额外时间,因为要修复权限问题。没有这个功能的。
选项E,mysql 二进制文件会被破坏。mysql的二进制不在datadir中,不受影响。
因此,选项AB正确。
讲解:
FORCE_PLUS_PERMANENT作用:
告诉mysql在启动的时候加载插件,并防止在运行时此插件被卸载,当卸载时会报错。
看题目:
题目中写的是FORCE_LOG_PERMANENT,这是出题者写错了,正确写法是FORCE_PLUS_PERMANENT。
看选项,只有C表达正确。
因此,选项C正确。
讲解:
MySQL Firewall是mysql enterprise版本独有的插件,全称MySQL Enterprise Firewall。
它是应用级别application-level的防火墙,起作用如下:
使DBA可以根据预先设置的SQL模式或者模板来允许或者拒绝SQL语句的执行。不符合SQL模式的SQL语句将被拒绝执行,以此来防止SQL注入攻击。这种符合SQL模板的SQL叫做allowlist。
它对每个mysql用户都单独设立一套SQL模式,或者一套profile。
profile有四种操作状态:
- OFF--关闭
- RECORDING--记录,或者训练模式,此模式下会让Firewall学习正常SQL并生成SQL模板列表。
- PROTECTING--保护模式,此模式下Firewall根据学习到是SQL模板列表来处理SQL,决定其允许执行或者拒绝执行。
- DETECTING--检测模式,此模式下Firewall不会阻止有侵入性或者破坏性的SQL执行(因为不在allowlist中),但会记录这些可以的SQL到日志中。
当MySQL Enterprise Firewall插件安装后,会有四个状态参数(Status Variables)来表现Firewall的允许状态:
- Firewall_access_denied--Firewall 拒绝执行的SQL数量
- Firewall_access_granted--Firewall 允许执行的SQL数量
- Firewall_access_suspicious--Firewall标记并记录的可以SQL的数量,只针对DETECTING模式.
- Firewall_cached_entries--Firewall记录的SQL数量,包括重复的SQL.
注意:Firewall针对的是SQL Statement,而不是connection。
看选项:
选项A,描述的是connection。错误。
选项B,描述的是在query cache中发现的allowlist,并且是DETECTING mode。错误。
选项C,描述的是connection。错误。
选项D,正确。
因此,选项D正确。
讲解:
防止SQL注入有如下方法:
- 使用prepared statements,它不允许拼接SQL,对SQL赋值管理严格。
- 使用procedure,存储过程中使用的是prepared statements。
- 不要拼接SQL语句,尤其是给SQL语句赋值时不要拼接。
看题目:
题目问的是哪个选项对防止sql注入攻击无效。
看选项:
选项ABD,都可以防止SQL注入。
选项C,使用connection control。这个并不能防止SQL攻击,前面我们讲过,它的作用是防止DDo攻击或暴力连接造成的压力过载攻击。
因此,选项C正确。
讲解:
禁用一个mysql用户有3种方法:
- ACCOUNT LOCK
- mysql_no_login
- DROP USER
看题目:
mysql instance中一个用户baduser@localhost已经被放弃了,如何禁止此用户将来再次登录。
看选项:
选项A,ACCOUNT LOCK。可以实现。
选项B,PASSWORD DISABLED。没有这种写法。
选项C,MAX_USER_CONNECTIONS=0。设置为0是无限制,并且这个参数也不是用在单个用户的,它是全局变量,设置方法为SET GLOBAL MAX_USER_CONNECTIONS=0。
选项D,DEFAULT ROLE NONE。给某个用户设置一个default role none只是收回去role角色带来的权限,其自身的权限依然存在,并可以继续登录。
选项E,IDENTIFIED WITH mysql_no_login。这个是mysql_no_login插件实现的功能。
如果安装了mysql_no_login插件,这样操作可以禁用此用户的登录。
安装方式如下:
INSTALL PLUGIN mysql_no_login SONAME 'mysql_no_login.so';
因此,选项AE正确。
第四讲上篇完成。
作者:老哥讲数据库
简介:数据库高级架构师 | Oracle 11g&12c OCM | MySQL 5.7&8.0 OCP
原创文章,转载请注明来源。