MySQL 8.0 OCP 查漏补缺-防火墙相关概念之二

最近在考MySQL 8.0的OCP ,开个专题专门查漏补缺下

基于8.0.26

只是做备忘,有的概念只是一笔带过,具体可自行搜索

由于该功能只在企业版上,这里没有环境,所有命令和图片来自官网

1. Firewall Profiles

防火墙使用profile来决定是否允许一个语句执行,它有三个属性

  • allowlist 该属性是一个规则集合来定义profile中哪些语句是可以通行的
  • 一个当前的可操作(operational )模式,使得profile可以在多个模式使用,这个后面介绍
  • profile的适用范围,这个定义什么客户端连接适用什么profile,包含:
    • account-based profiles 基于账号的,该profile叫做Account Profiles
    • group profiles 基于组的,该profile叫做Group Profiles,从8.0.23开始支持

这里注意:一个group可以包含多个account,account也可以同时属于多个group,account可以对应多个profile,只要profile包含该account.

默认情况下是没有任何profile的,这意味着所有语句都可以被执行,如果需要使用需要做如下操作:

  • 注册一个或多个profile到防火墙
  • 针对每个profile进行训练,以用来建立一个allowlist
  • 将经过训练的profile置于protecting 模式来过滤语句

2. Profile Operational Modes

上面我们说了Profile有三个属性,下面来讲第二个,可操作模式有如下取值:

  • OFF: 代表该profile未启用,防火墙会忽略它
  • RECORDING: 代表该profile处于训练模式(training mode),处于这种模式后所做的操作会被记录下来并加入到allowlist,这时当前连接的用户适用该profile,这里防火墙会合并一些语句来减少规则,如将where条件的值替换成为占位符(?),类似与绑定变量。

  • PROTECTING: 这个模式下防火墙会对过来的语句进行过滤,阻止不在allowlist里面的语句,如果设置了mysql_firewall_trace 变量,则会把reject的语句写入都错误日志

  • DETECTING: 处于该模式下的话不会reject不在allowlist里面的语句,会执行并将这些可疑的语句写入到错误日志

可以使用RESET命令来重置profile,这个命令会删除profile下所有的规则并设置成OFF状态

3. 注册一个Group Profiles

3.1 建立一个用户并赋权

CREATE USER 'member1'@'localhost' IDENTIFIED BY 'password'; 
GRANT ALL ON sakila.* TO 'member1'@'localhost';
grant firewall_admin on *.* to 'root'@'localhost';

3.2 注册 group profile并处理RECORDING 模式

CALL mysql.sp_set_firewall_group_mode('fwgrp', 'RECORDING');

3.3 将用户加入到组里

CALL mysql.sp_firewall_group_enlist('fwgrp', 'member1@localhost');

3.4 开始训练

这里使用member1@localhost用户执行写语句让防火墙将这些加入到allowlist中

该allowlist适用于组内的所有用户

SELECT title, release_year FROM film WHERE film_id = 1; 
UPDATE actor SET last_update = NOW() WHERE actor_id = 1; 
SELECT store_id, COUNT(*) FROM inventory GROUP BY store_id;

这时可以查看相关视图来确定信息

mysql> SELECT MODE FROM performance_schema.firewall_groups WHERE NAME = 'fwgrp';


SELECT * FROM performance_schema.firewall_membership WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID;


SELECT RULE FROM performance_schema.firewall_group_allowlist WHERE NAME = 'fwgrp';
Image.png

3.5 将profile设为protect状态

如果状态不设置成RECORDING以外的状态,mysql不会持久化规则,如果重启数据据会丢失allowlist的内容

CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');

如果需要可以再次进入到训练模式来继续训练

3.6 添加别的用户到组

如果需要可以增加别的用户

CALL mysql.sp_firewall_group_enlist('fwgrp', 'member2@localhost'); 
CALL mysql.sp_firewall_group_enlist('fwgrp', 'member3@localhost'); 
CALL mysql.sp_firewall_group_enlist('fwgrp', 'member4@localhost');

当然也可以删除

CALL mysql.sp_firewall_group_delist('fwgrp', 'member3@localhost');

3.7 禁用profile

CALL mysql.sp_set_firewall_group_mode(group, 'OFF');

3.8 重置profile

CALL mysql.sp_set_firewall_group_mode(group, 'RESET');

4. 注册一个Account Profiles

4.1 建立用户

CREATE USER 'fwuser'@'localhost' IDENTIFIED BY 'password'; 
GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
grant firewall_admin on *.* to 'root'@'localhost';

4.2 设置成RECORDING模式

CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'RECORDING');

4.3开始训练

SELECT first_name, last_name FROM customer WHERE customer_id = 1; 
UPDATE rental SET return_date = NOW() WHERE rental_id = 1; 
SELECT get_customer_balance(1, NOW());

这时可以查看相关状态

mysql> SELECT MODE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS WHERE USERHOST = 'fwuser@localhost';


mysql> SELECT RULE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST WHERE USERHOST = 'fwuser@localhost';
Image_2.png

4.4 设置成保护模式

CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'PROTECTING');

如果需要可以再次进入到训练模式来继续训练

4.5 设置成检测模式

CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'DETECTING');

4.6 禁用profile

CALL mysql.sp_set_firewall_mode(user, 'OFF');

4.7 重置profile

CALL mysql.sp_set_firewall_mode(user, 'RESET');

5.监控防火墙

使用如下命令查看

SHOW GLOBAL STATUS LIKE 'Firewall%';
Image_3.png

分别代表拒绝的,接受的,可疑的,加入的规则。

6. 将Account Profiles 变为 Group Profiles

由于Group Profiles 从8.0.23才有,如果哟需要可以进行迁移

CALL mysql.sp_migrate_firewall_user_to_group('admin@localhost', 'admins'); 
CALL mysql.sp_migrate_firewall_user_to_group('local_client@localhost', 'local_clients'); 
CALL mysql.sp_migrate_firewall_user_to_group('remote_client@localhost', 'remote_clients')

必须处于非recording状态,account profile必须存在,group profile必须不存在