文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  使用 MySQL 企业版防火墙

8.4.7.3 使用 MySQL 企业版防火墙

在使用 MySQL 企业版防火墙之前,请按照 第 8.4.7.2 节,“安装或卸载 MySQL 企业版防火墙” 中的说明进行安装。

本节介绍如何使用 SQL 语句配置 MySQL 企业版防火墙。或者,MySQL Workbench 6.3.4 或更高版本提供了一个用于防火墙控制的图形界面。参见 MySQL 企业版防火墙界面

启用或禁用防火墙

要启用或禁用防火墙,请设置 mysql_firewall_mode 系统变量。默认情况下,安装防火墙时此变量已启用。要显式控制初始防火墙状态,您可以在服务器启动时设置该变量。例如,要在选项文件中启用防火墙,请使用以下行

[mysqld]
mysql_firewall_mode=ON

修改 my.cnf 后,重新启动服务器以使新设置生效。

或者,要在运行时设置和持久化防火墙设置

SET PERSIST mysql_firewall_mode = OFF;
SET PERSIST mysql_firewall_mode = ON;

SET PERSIST 设置运行中的 MySQL 实例的值。它还会保存该值,使其在后续服务器重启时继续生效。要更改运行中的 MySQL 实例的值,而不让它在后续重启时继续生效,请使用 GLOBAL 关键字而不是 PERSIST。参见 第 15.7.6.1 节,“SET 语法用于变量赋值”

安排防火墙缓存重新加载

每次 MYSQL_FIREWALL 服务器端插件初始化时,它会从以下表加载数据到其内部缓存

  • firewall_whitelist

  • firewall_group_allowlist

  • firewall_users

  • firewall_groups

  • firewall_membership

在不重启服务器或重新安装服务器端插件的情况下,对插件外部数据的修改不会在内部反映出来。 mysql_firewall_reload_interval_seconds 系统变量使得能够以指定的时间间隔强制从表中重新加载内存缓存。默认情况下,定期间隔值设置为零,这将禁用重新加载。

要安排定期缓存重新加载,首先确保已安装并启用 scheduler 组件(参见 第 7.5.5 节,“调度程序组件”)。要检查组件的状态

SHOW VARIABLES LIKE 'component_scheduler%';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------|
| component_scheduler.enabled | On    |
+-----------------------------+-------+

安装防火墙后,在服务器启动时将 mysql_firewall_reload_interval_seconds 全局系统变量设置为 60 到 INT_MAX 宏值(主机服务器的平台)之间的数字。0 到 60(1 到 59)之间的值将重置为 60。例如

$> mysqld [server-options] --mysql-firewall-reload-interval-seconds=40
...
2023-08-31T17:46:35.043468Z 0 [Warning] [MY-015031] [Server] Plugin MYSQL_FIREWALL 
reported: 'Invalid reload interval specified: 40. Valid values are 0 (off) or 
greater than or equal to 60. Adjusting to 60.'
...

或者,要在启动时设置和持久化防火墙设置,请在只读变量名称之前加上 PERSIST_ONLY 关键字或 @@PERSIST_ONLY. 限定符

SET PERSIST_ONLY mysql_firewall_reload_interval_seconds = 120;
SET @@PERSIST_ONLY.mysql_firewall_reload_interval_seconds = 120;

修改变量后,重新启动服务器以使新设置生效。

分配防火墙权限

安装防火墙后,请将适当的权限授予用于管理防火墙的 MySQL 账户或账户。权限取决于账户应允许执行哪些防火墙操作

  • FIREWALL_EXEMPT 权限授予应免除防火墙限制的任何帐户。例如,这对于配置防火墙的数据库管理员很有用,以避免由于错误配置导致即使管理员也被锁定而无法执行语句的可能性。

  • FIREWALL_ADMIN 权限授予应具有完全管理防火墙访问权限的任何帐户。(一些管理防火墙功能可以通过具有 FIREWALL_ADMIN 已弃用的 SUPER 权限的帐户来调用,如各个功能描述中所示。)

  • FIREWALL_USER 权限授予应仅对其自己的防火墙规则具有管理访问权限的任何帐户。

  • 授予防火墙数据库中防火墙存储过程的 EXECUTE 权限。这些可能会调用管理功能,因此存储过程访问还需要前面提到的对这些功能所需的权限。防火墙数据库可以是 mysql 系统数据库或自定义模式(请参阅 安装 MySQL 企业版防火墙)。

注意

只有在安装防火墙时才能授予 FIREWALL_EXEMPTFIREWALL_ADMINFIREWALL_USER 权限,因为 MYSQL_FIREWALL 插件定义了这些权限。

防火墙概念

MySQL 服务器允许客户端连接并接收来自它们的 SQL 语句以执行。如果启用了防火墙,服务器会将每个传入的语句传递给它,这些语句不会立即因语法错误而失败。根据防火墙是否接受语句,服务器执行该语句或将错误返回给客户端。本节介绍防火墙如何完成接受或拒绝语句的任务。

防火墙配置文件

防火墙使用配置文件注册表来确定是否允许执行语句。配置文件具有以下属性

  • 允许列表。允许列表是定义哪些语句对配置文件可接受的规则集。

  • 当前操作模式。该模式使配置文件能够以不同的方式使用。例如:可以将配置文件置于训练模式以建立允许列表;允许列表可用于限制语句执行或入侵检测;配置文件可以完全禁用。

  • 适用范围。范围指示配置文件适用于哪些客户端连接

    • 防火墙支持基于帐户的配置文件,以便每个配置文件都与特定的客户端帐户(客户端用户名和主机名组合)匹配。例如,您可以注册一个帐户配置文件,其允许列表适用于来自 admin@localhost 的连接,以及另一个帐户配置文件,其允许列表适用于来自 [email protected] 的连接。

    • 防火墙支持组配置文件,这些配置文件可以拥有多个帐户作为成员,配置文件允许列表对所有成员均等地适用。组配置文件使管理更轻松,并为需要将给定允许列表规则集应用于多个帐户的部署提供更大的灵活性。

最初,不存在任何配置文件,因此默认情况下,防火墙接受所有语句,并且不会影响 MySQL 帐户可以执行的语句。要应用防火墙保护功能,需要执行显式操作

  • 在防火墙中注册一个或多个配置文件。

  • 通过为每个配置文件建立允许列表来训练防火墙;即配置文件允许客户端执行的语句类型。

  • 将经过训练的配置文件置于保护模式,以强化 MySQL,防止未经授权的语句执行

    • MySQL 将每个客户端会话与特定用户名和主机名组合相关联。此组合是 会话帐户

    • 对于每个客户端连接,防火墙使用会话帐户来确定哪些配置文件适用于处理来自客户端的传入语句。

      防火墙仅接受适用配置文件允许列表允许的语句。

大多数防火墙原则对组配置文件和帐户配置文件相同。两种配置文件在以下方面有所不同

  • 帐户配置文件允许列表仅适用于单个帐户。组配置文件允许列表在会话帐户与作为该组成员的任何帐户匹配时适用。

  • 要使用帐户配置文件将允许列表应用于多个帐户,需要为每个帐户注册一个配置文件,并在每个配置文件中复制允许列表。这需要单独训练每个帐户配置文件,因为每个配置文件都必须使用与其关联的单个帐户进行训练。

    组配置文件允许列表适用于多个帐户,无需为每个帐户复制。可以使用组成员帐户中的任何一个或所有帐户来训练组配置文件,也可以将训练限制为任何单个成员。无论哪种方式,允许列表都适用于所有成员。

  • 帐户配置文件名称基于特定用户名和主机名组合,这些组合取决于哪些客户端连接到 MySQL 服务器。组配置文件名称由防火墙管理员选择,没有任何限制,除了它们必须为 1 到 288 个字符之外。

注意

由于组配置文件优于帐户配置文件的优势,并且具有单个成员帐户的组配置文件在逻辑上等效于该帐户的帐户配置文件,因此建议将所有新的防火墙配置文件创建为组配置文件。帐户配置文件已弃用,并且将在未来的 MySQL 版本中删除。有关转换现有帐户配置文件的帮助,请参阅 将帐户配置文件迁移到组配置文件

防火墙提供的基于配置文件的保护使您可以实现以下策略

  • 如果应用程序具有独特的保护要求,请将其配置为使用不用于任何其他目的的帐户,并为该帐户设置组配置文件或帐户配置文件。

  • 如果相关应用程序共享保护要求,请将每个应用程序与其自己的帐户相关联,然后将这些应用程序帐户添加为同一组配置文件的成员。或者,将所有应用程序配置为使用相同的帐户,并将它们与该帐户的帐户配置文件相关联。

防火墙语句匹配

防火墙执行的语句匹配不使用从客户端接收的 SQL 语句。相反,服务器将传入的语句转换为规范化的摘要形式,防火墙操作使用这些摘要。语句规范化的优点是它使类似的语句能够使用单个模式进行分组和识别。例如,以下语句彼此不同

SELECT first_name, last_name FROM customer WHERE customer_id = 1;
select first_name, last_name from customer where customer_id = 99;
SELECT first_name, last_name FROM customer WHERE customer_id = 143;

但它们都具有相同的规范化摘要形式

SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ?

通过使用规范化,防火墙允许列表可以存储摘要,每个摘要匹配从客户端接收的许多不同语句。有关规范化和摘要的更多信息,请参阅 第 29.10 节,“性能架构语句摘要和采样”

警告

max_digest_length 系统变量设置为零会禁用摘要生成,这也将禁用需要摘要的服务器功能,例如 MySQL 企业版防火墙。

配置文件操作模式

注册到防火墙的每个配置文件都有其自己的操作模式,从以下值中选择

  • OFF:此模式禁用配置文件。防火墙认为它处于非活动状态并忽略它。

  • RECORDING:这是防火墙训练模式。从与配置文件匹配的客户端接收的传入语句被认为对配置文件可接受,并成为其 指纹 的一部分。防火墙记录每个语句的规范化摘要形式,以了解配置文件的可接受语句模式。每个模式都是一个规则,规则的并集是配置文件允许列表。

    组配置文件和帐户配置文件之间的区别在于,组配置文件的语句记录可以限制为从单个组成员(训练成员)接收的语句。

  • PROTECTING:在此模式下,配置文件允许或阻止语句执行。防火墙将传入语句与配置文件允许列表进行匹配,仅接受匹配的语句,并拒绝不匹配的语句。在 RECORDING 模式下训练配置文件后,将其切换到 PROTECTING 模式,以强化 MySQL,防止与允许列表不符的语句访问。如果 mysql_firewall_trace 系统变量已启用,防火墙还会将拒绝的语句写入错误日志。

  • DETECTING:此模式检测但不会阻止入侵(由于与配置文件允许列表中没有任何内容匹配而可疑的语句)。在 DETECTING 模式下,防火墙会将可疑语句写入错误日志,但会接受它们,不会拒绝访问。

当配置文件被分配上述任何模式值时,防火墙将在配置文件中存储该模式。防火墙模式设置操作还允许 RESET 模式值,但此值不会被存储:将配置文件设置为 RESET 模式会导致防火墙删除配置文件的所有规则,并将其模式设置为 OFF

注意

写入错误日志中的消息,无论是 DETECTING 模式,还是因为 mysql_firewall_trace 已启用,都以 Note 的形式写入,它们是信息消息。要确保此类消息出现在错误日志中,并且不会被丢弃,请确保错误日志记录详细程度足以包含信息消息。例如,如果您使用基于优先级的日志过滤,如 第 7.4.2.5 节,“基于优先级的错误日志过滤(log_filter_internal)” 中所述,请将 log_error_verbosity 系统变量设置为 3。

多个配置文件应用时防火墙语句处理

为简便起见,后面几节介绍如何设置配置文件,它们都假设防火墙将来自客户端的传入语句与单个配置文件(组配置文件或帐户配置文件)进行匹配。但防火墙操作可能更复杂

  • 组配置文件可以包含多个帐户作为成员。

  • 一个帐户可以是多个组配置文件的成员。

  • 多个配置文件可以匹配给定的客户端。

以下描述涵盖了防火墙操作的一般情况,当可能有多个配置文件适用于传入语句时。

如前所述,MySQL 将每个客户端会话与称为 会话帐户 的特定用户名和主机名组合相关联。防火墙将会话帐户与注册的配置文件进行匹配,以确定哪些配置文件适用于处理来自该会话的传入语句

  • 防火墙会忽略非活动配置文件(模式为 OFF 的配置文件)。

  • 会话帐户会匹配每个包含具有相同用户和主机的成员的活动组配置文件。可能有多个这样的组配置文件。

  • 如果存在,会话帐户会匹配具有相同用户和主机的活动帐户配置文件。最多只有一个这样的帐户配置文件。

换句话说,会话帐户可以匹配 0 个或多个活动组配置文件,以及 0 个或 1 个活动帐户配置文件。这意味着 0 个、1 个或多个防火墙配置文件适用于给定的会话,对于这些配置文件,防火墙会对每个传入语句进行以下处理

  • 如果不存在适用配置文件,防火墙不会施加任何限制,并接受该语句。

  • 如果存在适用配置文件,它们的模式将决定语句处理方式。

    • 防火墙将语句记录在每个处于 RECORDING 模式的适用配置文件的允许列表中。

    • 对于每个处于 DETECTING 模式的适用配置文件,如果语句可疑(与配置文件允许列表不匹配),防火墙会将语句写入错误日志。

    • 如果至少一个适用配置文件处于 RECORDINGDETECTING 模式(这些模式接受所有语句),或者如果语句与至少一个处于 PROTECTING 模式的适用配置文件的允许列表匹配,则防火墙接受该语句。否则,防火墙将拒绝该语句(如果 mysql_firewall_trace 系统变量已启用,则将语句写入错误日志)。

考虑到这些描述,接下来的部分将回归到简单的情况,即只有一个组配置文件或一个帐户配置文件适用,并涵盖如何设置每种类型的配置文件。

注册防火墙组配置文件

MySQL Enterprise Firewall 支持注册组配置文件。组配置文件可以有多个帐户作为其成员。要使用防火墙组配置文件来保护 MySQL 免受来自给定帐户的传入语句的影响,请执行以下步骤

  1. 注册组配置文件并将其置于 RECORDING 模式。

  2. 将成员帐户添加到组配置文件。

  3. 使用成员帐户连接到 MySQL 服务器并执行要学习的语句。这将训练组配置文件并建立构成配置文件允许列表的规则。

  4. 将要成为组成员的其他帐户添加到组配置文件。

  5. 将组配置文件切换到 PROTECTING 模式。当客户端使用组配置文件的任何成员帐户连接到服务器时,配置文件允许列表会限制语句执行。

  6. 如果需要额外的训练,请再次将组配置文件切换到 RECORDING 模式,使用新的语句模式更新其允许列表,然后将其切换回 PROTECTING 模式。

请遵守这些与防火墙相关的帐户引用的指南

  • 注意帐户引用发生的上下文。要为防火墙操作命名帐户,请将其指定为一个单引号字符串 ('user_name@host_name')。这与 MySQL 用于语句(如 CREATE USERGRANT)的常规约定不同,对于这些语句,您需要分别引用帐户名的用户和主机部分 ('user_name'@'host_name')。

    为防火墙操作命名帐户需要使用单引号字符串,这意味着您不能使用在用户名中包含 @ 字符的帐户。

  • 防火墙根据服务器验证的实际用户名和主机名来评估针对帐户的语句。在配置文件中注册帐户时,请勿使用通配符或网络掩码

    • 假设存在名为 me@%.example.org 的帐户,并且客户端使用它从主机 abc.example.org 连接到服务器。

    • 帐户名包含一个 % 通配符,但服务器验证客户端的用户名为 me,主机名为 abc.example.com,而这是防火墙看到的。

    • 因此,用于防火墙操作的帐户名应该是 [email protected] 而不是 me@%.example.org

以下步骤说明了如何使用防火墙注册组配置文件,训练防火墙识别该配置文件的合法语句(其允许列表),使用该配置文件来保护 MySQL 免受不可接受语句的执行,以及添加和删除组成员。示例使用组配置文件名为 fwgrp。示例配置文件假定用于访问 sakila 数据库中表的应用程序的客户端(在 https://dev.mysqlserver.cn/doc/index-other.html 中提供)。

使用管理员 MySQL 帐户执行此过程中的步骤,除了指定由防火墙组配置文件的成员帐户执行的步骤。对于由成员帐户执行的语句,默认数据库应该是 sakila。(您可以通过相应地调整说明来使用其他数据库。)

  1. 如有必要,请创建要成为 fwgrp 组配置文件成员的帐户,并授予其适当的访问权限。以下显示了对一个成员的语句(选择适当的密码)

    CREATE USER 'member1'@'localhost' IDENTIFIED BY 'password';
    GRANT ALL ON sakila.* TO 'member1'@'localhost';
  2. 使用 sp_set_firewall_group_mode() 存储过程将组配置文件注册到防火墙,并将配置文件置于 RECORDING(训练)模式

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

    如果您在自定义模式中安装了 MySQL Enterprise Firewall,那么请对您的系统进行适当的替换。例如,如果防火墙安装在 fwdb 模式中,那么请像这样执行存储过程

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

  3. 使用 sp_firewall_group_enlist() 存储过程添加一个初始成员帐户,用于训练组配置文件允许列表

    CALL mysql.sp_firewall_group_enlist('fwgrp', 'member1@localhost');
  4. 要使用初始成员帐户训练组配置文件,请从服务器主机以 member1 的身份连接到服务器,以便防火墙看到 member1@localhost 的会话帐户。然后执行一些要被视为对配置文件合法的语句。例如

    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;

    防火墙从 member1@localhost 帐户接收语句。由于该帐户是处于 RECORDING 模式的 fwgrp 配置文件的成员,因此防火墙将语句解释为适用于 fwgrp,并将语句的规范化摘要形式记录为 fwgrp 允许列表中的规则。这些规则将适用于所有成为 fwgrp 成员的帐户。

    注意

    fwgrp 组配置文件在 RECORDING 模式下接收语句之前,其允许列表为空,这相当于 拒绝所有。 任何语句都无法与空允许列表匹配,这会带来以下影响

    • 组配置文件无法切换到 PROTECTING 模式。它将拒绝所有语句,有效地禁止组成员帐户执行任何语句。

    • 组配置文件可以切换到 DETECTING 模式。在这种情况下,配置文件接受所有语句,但将其记录为可疑。

  5. 此时,组配置文件信息会被缓存,包括其名称、成员资格和允许列表。要查看此信息,请查询 Performance Schema 防火墙表

    mysql> SELECT MODE FROM performance_schema.firewall_groups
           WHERE NAME = 'fwgrp';
    +-----------+
    | MODE      |
    +-----------+
    | RECORDING |
    +-----------+
    mysql> SELECT * FROM performance_schema.firewall_membership
           WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID;
    +----------+-------------------+
    | GROUP_ID | MEMBER_ID         |
    +----------+-------------------+
    | fwgrp    | member1@localhost |
    +----------+-------------------+
    mysql> SELECT RULE FROM performance_schema.firewall_group_allowlist
           WHERE NAME = 'fwgrp';
    +----------------------------------------------------------------------+
    | RULE                                                                 |
    +----------------------------------------------------------------------+
    | SELECT @@`version_comment` LIMIT ?                                   |
    | UPDATE `actor` SET `last_update` = NOW ( ) WHERE `actor_id` = ?      |
    | SELECT `title` , `release_year` FROM `film` WHERE `film_id` = ?      |
    | SELECT `store_id` , COUNT ( * ) FROM `inventory` GROUP BY `store_id` |
    +----------------------------------------------------------------------+
    注意

    来自 mysql 客户端在您连接到服务器时自动发送的语句会产生 @@version_comment 规则。

    重要

    在与应用程序使用情况匹配的条件下训练防火墙。例如,为了确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,则也使用连接器来训练防火墙。这样,这些初始语句就会成为与应用程序关联的组配置文件的允许列表的一部分。

  6. 再次调用 sp_set_firewall_group_mode() 将组配置文件切换到 PROTECTING 模式

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

    将组配置文件从 RECORDING 模式切换出去会将其缓存的数据同步到提供持久底层存储的防火墙数据库表。如果您不切换正在记录的配置文件的模式,则缓存的数据不会写入持久存储,并在服务器重新启动时丢失。防火墙数据库可以是 mysql 系统数据库或自定义模式(请参阅 安装 MySQL Enterprise Firewall)。

  7. 将要成为成员的其他帐户添加到组配置文件

    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');

    使用 member1@localhost 帐户训练的配置文件允许列表现在也适用于其他帐户。

  8. 要验证更新后的组成员资格,请再次查询 firewall_membership

    mysql> SELECT * FROM performance_schema.firewall_membership
           WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID;
    +----------+-------------------+
    | GROUP_ID | MEMBER_ID         |
    +----------+-------------------+
    | fwgrp    | member1@localhost |
    | fwgrp    | member2@localhost |
    | fwgrp    | member3@localhost |
    | fwgrp    | member4@localhost |
    +----------+-------------------+
  9. 通过使用组中的任何帐户来执行一些可接受和不可接受的语句,来测试组配置文件是否符合防火墙。防火墙会将帐户发出的每个语句与配置文件允许列表进行匹配,并接受或拒绝它

    • 该语句与训练语句并不完全相同,但会产生与其中之一相同的规范化语句,因此防火墙会接受它

      mysql> SELECT title, release_year FROM film WHERE film_id = 98;
      +-------------------+--------------+
      | title             | release_year |
      +-------------------+--------------+
      | BRIGHT ENCOUNTERS |         2006 |
      +-------------------+--------------+
    • 这些语句与允许列表中的任何内容都不匹配,因此防火墙会拒绝每个语句并显示错误

      mysql> SELECT title, release_year FROM film WHERE film_id = 98 OR TRUE;
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> SHOW TABLES LIKE 'customer%';
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> TRUNCATE TABLE mysql.slow_log;
      ERROR 1045 (28000): Statement was blocked by Firewall
    • 如果 mysql_firewall_trace 系统变量已启用,则防火墙还会将被拒绝的语句写入错误日志。例如

      [Note] Plugin MYSQL_FIREWALL reported:
      'ACCESS DENIED for 'member1@localhost'. Reason: No match in allowlist.
      Statement: TRUNCATE TABLE `mysql` . `slow_log`'

      这些日志消息可能有助于识别攻击的来源,如果需要的话。

  10. 如果需要从组配置文件中删除成员,请使用 sp_firewall_group_delist() 存储过程,而不是 sp_firewall_group_enlist()

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

现在,防火墙组配置文件已针对成员帐户进行训练。当客户端使用组中的任何帐户连接并尝试执行语句时,配置文件会保护 MySQL 免受与配置文件允许列表不匹配的语句的影响。

刚才显示的过程只在训练其允许列表之前将一个成员添加到组配置文件。这样做通过限制哪些帐户可以将新的合法语句添加到允许列表来更好地控制训练阶段。如果需要额外的训练,您可以将配置文件切换回 RECORDING 模式

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

但是,这会使组中的任何成员都可以执行语句并将其添加到允许列表。要将额外的训练限制为单个组成员,请调用 sp_set_firewall_group_mode_and_user(),它类似于 sp_set_firewall_group_mode(),但它会多出一个参数,用于指定哪个帐户被允许在 RECORDING 模式下训练配置文件。例如,要仅允许 member4@localhost 进行训练,请执行以下操作

CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', 'member4@localhost');

这使指定的帐户可以进行额外的训练,而无需删除其他组成员。他们可以执行语句,但这些语句不会添加到允许列表。(但是请记住,在 RECORDING 模式下,其他成员可以执行 任何语句。)

注意

为了避免在将特定帐户指定为组配置文件的训练帐户时出现意外行为,请始终确保该帐户是该组的成员。

在额外训练之后,将组配置文件切换回 PROTECTING 模式

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

通过 sp_set_firewall_group_mode_and_user() 建立的训练帐户会保存在组配置文件中,因此防火墙会记住它,以备日后需要更多训练时使用。因此,如果您调用 sp_set_firewall_group_mode()(不带训练帐户参数),则当前的配置文件训练帐户 member4@localhost 会保持不变。

要清除训练帐户(如果确实希望允许所有组成员在 RECORDING 模式下执行训练),请调用 sp_set_firewall_group_mode_and_user() 并为帐户参数传递 NULL

CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', NULL);

可以通过将不匹配的语句记录为可疑来检测入侵,而无需拒绝访问。首先,将组配置文件置于 DETECTING 模式

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

然后,使用成员帐户执行与组配置文件允许列表不匹配的语句。在 DETECTING 模式下,防火墙会允许不匹配的语句执行

mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+

此外,防火墙还会将一条消息写入错误日志

[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'member1@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'

要禁用组配置文件,请将其模式更改为 OFF

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

要忘记配置文件的所有训练并将其禁用,请重置它

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

重置操作将导致防火墙删除配置文件的所有规则并将模式设置为OFF

注册防火墙账户配置文件

MySQL 企业防火墙允许注册与单个账户相对应的配置文件。要使用防火墙账户配置文件保护 MySQL 免受来自给定账户的传入语句的攻击,请遵循以下步骤

  1. 注册账户配置文件并将其置于RECORDING模式。

  2. 使用该账户连接到 MySQL 服务器并执行要学习的语句。这将训练账户配置文件并建立构成配置文件允许列表的规则。

  3. 将账户配置文件切换到PROTECTING模式。当客户端使用该账户连接到服务器时,账户配置文件允许列表将限制语句执行。

  4. 如果需要额外的训练,请再次将账户配置文件切换到RECORDING模式,使用新的语句模式更新其允许列表,然后将其切换回PROTECTING模式。

请遵守这些与防火墙相关的帐户引用的指南

  • 注意帐户引用发生的上下文。要为防火墙操作命名帐户,请将其指定为一个单引号字符串 ('user_name@host_name')。这与 MySQL 用于语句(如 CREATE USERGRANT)的常规约定不同,对于这些语句,您需要分别引用帐户名的用户和主机部分 ('user_name'@'host_name')。

    为防火墙操作命名帐户需要使用单引号字符串,这意味着您不能使用在用户名中包含 @ 字符的帐户。

  • 防火墙根据服务器验证的实际用户名和主机名来评估针对帐户的语句。在配置文件中注册帐户时,请勿使用通配符或网络掩码

    • 假设存在名为 me@%.example.org 的帐户,并且客户端使用它从主机 abc.example.org 连接到服务器。

    • 帐户名包含一个 % 通配符,但服务器验证客户端的用户名为 me,主机名为 abc.example.com,而这是防火墙看到的。

    • 因此,用于防火墙操作的帐户名应该是 [email protected] 而不是 me@%.example.org

以下步骤展示了如何使用防火墙注册账户配置文件,训练防火墙以了解该配置文件的允许语句(其允许列表),并使用该配置文件保护 MySQL 免受账户执行不可接受的语句的攻击。示例账户fwuser@localhost假定用于访问sakila数据库中的表的应用程序(可在https://dev.mysqlserver.cn/doc/index-other.html获得)。

使用管理员 MySQL 账户执行此步骤中的步骤,除了那些指定由与防火墙注册的账户配置文件相对应的fwuser@localhost账户执行的步骤。对于使用此账户执行的语句,默认数据库应该是sakila。(您可以通过相应地调整说明来使用不同的数据库。)

  1. 如果需要,创建用于执行语句的账户(选择合适的密码)并授予其对sakila数据库的权限

    CREATE USER 'fwuser'@'localhost' IDENTIFIED BY 'password';
    GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
  2. 使用sp_set_firewall_mode()存储过程将账户配置文件注册到防火墙并将其置于RECORDING(训练)模式

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

    如果您在自定义模式中安装了 MySQL Enterprise Firewall,那么请对您的系统进行适当的替换。例如,如果防火墙安装在 fwdb 模式中,那么请像这样执行存储过程

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

  3. 要训练已注册的账户配置文件,请从服务器主机以fwuser身份连接到服务器,以便防火墙看到fwuser@localhost的会话账户。然后使用该账户执行一些要视为对配置文件合法的语句。例如

    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());

    由于配置文件处于RECORDING模式,因此防火墙会将语句的规范化摘要形式记录为配置文件允许列表中的规则。

    注意

    fwuser@localhost账户配置文件在RECORDING模式下接收语句之前,其允许列表为空,这等同于拒绝所有。没有任何语句可以匹配空允许列表,这具有以下含义

    • 账户配置文件不能切换到PROTECTING模式。它将拒绝每个语句,有效地阻止账户执行任何语句。

    • 账户配置文件可以切换到DETECTING模式。在这种情况下,配置文件会接受每个语句,但将其记录为可疑的。

  4. 此时,账户配置文件信息已缓存。要查看此信息,请查询INFORMATION_SCHEMA防火墙表

    mysql> SELECT MODE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS
           WHERE USERHOST = 'fwuser@localhost';
    +-----------+
    | MODE      |
    +-----------+
    | RECORDING |
    +-----------+
    mysql> SELECT RULE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST
           WHERE USERHOST = 'fwuser@localhost';
    +----------------------------------------------------------------------------+
    | RULE                                                                       |
    +----------------------------------------------------------------------------+
    | SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ?  |
    | SELECT `get_customer_balance` ( ? , NOW ( ) )                              |
    | UPDATE `rental` SET `return_date` = NOW ( ) WHERE `rental_id` = ?          |
    | SELECT @@`version_comment` LIMIT ?                                         |
    +----------------------------------------------------------------------------+
    注意

    来自 mysql 客户端在您连接到服务器时自动发送的语句会产生 @@version_comment 规则。

    重要

    在与应用程序使用匹配的条件下训练防火墙。例如,为了确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,请使用连接器训练防火墙。这使得这些初始语句成为与应用程序关联的账户配置文件的允许列表的一部分。

  5. 再次调用sp_set_firewall_mode(),这次将账户配置文件切换到PROTECTING模式

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

    将账户配置文件从RECORDING模式切换出去会将其缓存的数据同步到提供持久底层存储的防火墙数据库表中。如果您不切换正在记录的配置文件的模式,则缓存数据不会写入持久存储,并在服务器重启时丢失。防火墙数据库可以是mysql系统数据库或自定义模式(请参阅安装 MySQL 企业防火墙)。

  6. 使用该账户执行一些可接受和不可接受的语句来测试账户配置文件。防火墙会将来自账户的每个语句与配置文件允许列表进行匹配,并接受或拒绝它

    • 该语句与训练语句并不完全相同,但会产生与其中之一相同的规范化语句,因此防火墙会接受它

      mysql> SELECT first_name, last_name FROM customer WHERE customer_id = '48';
      +------------+-----------+
      | first_name | last_name |
      +------------+-----------+
      | ANN        | EVANS     |
      +------------+-----------+
    • 这些语句与允许列表中的任何内容都不匹配,因此防火墙会拒绝每个语句并显示错误

      mysql> SELECT first_name, last_name FROM customer WHERE customer_id = 1 OR TRUE;
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> SHOW TABLES LIKE 'customer%';
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> TRUNCATE TABLE mysql.slow_log;
      ERROR 1045 (28000): Statement was blocked by Firewall
    • 如果 mysql_firewall_trace 系统变量已启用,则防火墙还会将被拒绝的语句写入错误日志。例如

      [Note] Plugin MYSQL_FIREWALL reported:
      'ACCESS DENIED for fwuser@localhost. Reason: No match in allowlist.
      Statement: TRUNCATE TABLE `mysql` . `slow_log`'

      这些日志消息可能有助于识别攻击的来源,如果需要的话。

防火墙账户配置文件现在已针对fwuser@localhost账户进行训练。当客户端使用该账户连接并尝试执行语句时,该配置文件会保护 MySQL 免受配置文件允许列表未匹配的语句的攻击。

可以通过将非匹配语句记录为可疑的(而不拒绝访问)来检测入侵。首先,将账户配置文件置于DETECTING模式

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

然后,使用该账户执行与账户配置文件允许列表不匹配的语句。在DETECTING模式下,防火墙允许执行不匹配的语句

mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+

此外,防火墙还会将一条消息写入错误日志

[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'fwuser@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'

要禁用账户配置文件,请将其模式更改为OFF

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

要忘记配置文件的所有训练并将其禁用,请重置它

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

重置操作将导致防火墙删除配置文件的所有规则并将模式设置为OFF

监控防火墙

要评估防火墙活动,请检查其状态变量。例如,在执行前面显示的步骤来训练和保护fwgrp组配置文件后,变量如下所示

mysql> SHOW GLOBAL STATUS LIKE 'Firewall%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Firewall_access_denied     | 3     |
| Firewall_access_granted    | 4     |
| Firewall_access_suspicious | 1     |
| Firewall_cached_entries    | 4     |
+----------------------------+-------+

这些变量分别表示被拒绝、被接受、被记录为可疑的以及添加到缓存中的语句数量。由于Firewall_access_granted计数为 4,因为mysql客户端在您使用注册账户连接的三次时每次都发送了@@version_comment语句,加上在DETECTING模式下未被阻止的SHOW TABLES语句。

将账户配置文件迁移到组配置文件

MySQL 企业防火墙支持每个都应用于单个账户的账户配置文件,以及每个都可应用于多个账户的组配置文件。当需要将相同的允许列表应用于多个账户时,组配置文件可以简化管理:与其为每个账户创建一个账户配置文件并在所有这些配置文件中复制允许列表,不如创建一个组配置文件并将这些账户设为其成员。然后,组允许列表将应用于所有账户。

具有单个成员账户的组配置文件在逻辑上等同于该账户的账户配置文件,因此可以使用组配置文件来专门管理防火墙,而不是混合使用账户配置文件和组配置文件。对于新的防火墙安装,这可以通过一致地创建新的配置文件为组配置文件并避免使用账户配置文件来实现。

由于组配置文件提供了更大的灵活性,因此建议将所有新的防火墙配置文件创建为组配置文件。账户配置文件已弃用,并且可能会在未来的 MySQL 版本中被删除。对于从已经包含账户配置文件的防火墙安装进行升级,MySQL 企业防火墙包含一个名为sp_migrate_firewall_user_to_group()的存储过程,以帮助您将账户配置文件转换为组配置文件。要使用它,请以具有FIREWALL_ADMIN权限的用户身份执行以下步骤

  1. 运行firewall_profile_migration.sql脚本以安装sp_migrate_firewall_user_to_group()存储过程。该脚本位于 MySQL 安装的share目录中。

    在命令行上指定与您之前为防火墙安装定义的相同的防火墙数据库名称。此示例指定系统数据库mysql

    $> mysql -u root -p -D mysql < firewall_profile_migration.sql
    Enter password: (enter root password here)

    如果您在自定义模式中安装了 MySQL 企业防火墙,请对您的系统进行适当的替换。

  2. 通过查询信息模式MYSQL_FIREWALL_USERS表来确定哪些账户配置文件存在。例如

    mysql> SELECT USERHOST FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS;
    +-------------------------------+
    | USERHOST                      |
    +-------------------------------+
    | admin@localhost               |
    | local_client@localhost        |
    | [email protected] |
    +-------------------------------+
  3. 对于上一步识别的每个账户配置文件,将其转换为组配置文件。如果需要,请将mysql.前缀替换为实际的防火墙数据库名称

    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模式,并且组配置文件也不得已经存在。生成的组配置文件将具有该命名账户作为其唯一的注册成员,该成员也设置为组训练账户。组配置文件的操作模式取自账户配置文件的操作模式。

  4. (可选)删除sp_migrate_firewall_user_to_group()

    DROP PROCEDURE IF EXISTS mysql.sp_migrate_firewall_user_to_group;

    如果您在自定义模式中安装了 MySQL 企业防火墙,请对您的系统进行适当的替换。

有关sp_migrate_firewall_user_to_group()的更多详细信息,请参阅防火墙杂项存储过程