Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Using MySQL Enterprise Firewall

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 语法 for 变量赋值”

计划防火墙缓存重新加载

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

  • firewall_whitelist

  • firewall_group_allowlist

  • firewall_users

  • firewall_groups

  • firewall_membership

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

要计划定期缓存重新加载,首先确保 scheduler 组件已安装并启用(请参阅第 7.5.5 节,“Scheduler 组件”)。要检查组件的状态:

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 权限给任何应该免除防火墙限制的帐户。这对于数据库管理员非常有用,例如,配置防火墙,以避免可能的misconfiguration 导致管理员也被锁定无法执行语句。

  • 授予 FIREWALL_ADMIN 权限给任何应该拥有完全管理防火墙访问权的帐户。(一些管理防火墙函数可以由拥有 FIREWALL_ADMIN 已弃用的 SUPER 权限的帐户调用,如函数描述中所示。)

  • 授予 FIREWALL_USER 权限给任何应该拥有管理防火墙规则的帐户。

  • 授予 EXECUTE 权限以便在防火墙数据库中执行存储过程。这些可能会调用管理函数,因此存储过程访问也需要之前所需的权限。防火墙数据库可以是 mysql 系统数据库或自定义模式(见 安装 MySQL 企业防火墙)。

Note

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

防火墙概念

MySQL 服务器允许客户端连接,并从客户端接收要执行的 SQL 语句。如果防火墙启用,服务器将每个入站语句传递给防火墙,以确定是否执行语句。以下部分描述防火墙如何完成语句的接受或拒绝。

Firewall Profiles

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

  • 允许列表。允许列表是配置文件中定义的可接受语句的集合。

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

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

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

    • 防火墙支持组配置文件,可以拥有多个帐户作为成员,配置文件的允许列表将同等地应用于所有成员。组配置文件使得管理更加容易,并且为需要将给定的允许列表规则应用于多个帐户的部署提供了更大的灵活性。

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

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

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

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

    • MySQL 将每个客户会话关联到特定的用户名和主机名组合。这组合是 会话帐户

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

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

大多数防火墙原则同样适用于组配置文件和帐户配置文件。两种类型的配置文件的区别在于:

  • 帐户配置文件的允许列表仅适用于单个帐户。组配置文件的允许列表适用于任何成员帐户。

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

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

  • 帐户配置文件的名称基于特定的用户名和主机名组合,取决于哪些客户连接到 MySQL 服务器。组配置文件的名称由防火墙管理员选择,唯一的限制是名称长度必须在 1 到 288 个字符之间。

Note

由于组配置文件相比帐户配置文件的优势,以及组配置文件可以等同于单个帐户的帐户配置文件,因此建议所有新的防火墙配置文件都创建为组配置文件。帐户配置文件自 MySQL 8.0.26 起弃用,并将在未来 MySQL 版本中删除。有关将现有帐户配置文件迁移到组配置文件的帮助,请参阅 迁移到组配置文件

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

  • 如果应用程序具有独特的保护要求,可以将其配置为使用专门的帐户,并为该帐户设置组配置文件或帐户配置文件。

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

Firewall Statement Matching

防火墙执行的语句匹配不使用来自客户的 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 节,“性能模式语句摘要和采样”

Warning

max_digest_length 系统变量设置为零将禁用摘要生产,这也将禁用服务器的相关功能,例如 MySQL Enterprise Firewall。

Profile Operational Modes

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

  • OFF:该模式禁用配置文件。防火墙将其视为不活动的,并忽略它。

  • RECORDING:这是防火墙的训练模式。来自客户的入站语句被视为该配置文件的可接受语句,并成为其 指纹。 防火墙记录每个语句的标准化摘要形式,以学习配置文件的可接受语句模式。每个模式都是一个规则,规则的集合就是配置文件的允许列表。

    组和账户配置文件之间的差异是,组配置文件的语句记录可以限制为来自单个组成员(训练成员)的语句。

  • PROTECTING:在这种模式下,配置文件允许或阻止语句执行。防火墙将入站语句与配置文件的允许列表进行匹配,只接受匹配的语句,而拒绝不匹配的语句。在 RECORDING 模式下训练配置文件后,切换到 PROTECTING 模式,以硬化 MySQL 防止访问不在允许列表中的语句。如果启用了 mysql_firewall_trace 系统变量,防火墙还将被拒绝的语句写入错误日志。

  • DETECTING:该模式检测但不阻止入侵(语句与允许列表不匹配)。在 DETECTING 模式下,防火墙将可疑语句写入错误日志,但接受语句而不拒绝访问。

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

Note

错误日志中的消息是在 DETECTING 模式下或因为 mysql_firewall_trace 启用时写入的。这些消息作为 Notes 写入,信息性消息。确保错误日志的详细程度足以包括信息消息。例如,如果您使用基于优先级的日志过滤,如 第 7.4.2.5 节,“基于优先级的错误日志过滤(log_filter_internal)”所述,设置 log_error_verbosity 系统变量的值为 3。

Firewall Statement Handling When Multiple Profiles Apply

为了简单起见,后面的章节描述如何设置配置文件,假设防火墙仅匹配来自客户端的语句与单个配置文件,或者组配置文件或账户配置文件。但是,防火墙操作可以更加复杂:

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

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

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

以下描述涵盖了防火墙的通用情况,多个配置文件可能适用于入站语句。

如前所述,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,这就是防火墙所看到的。

    • 因此,用于防火墙操作的账户名称是me@abc.example.org而不是me@%.example.org

以下过程显示了如何注册组配置文件、训练防火墙以了解该配置文件的可接受语句(其允许列表)、使用该配置文件保护MySQL免受不可接受语句的执行,并添加和删除组成员。该示例使用组配置文件名称fwgrp。该示例配置文件假设用于访问sakila数据库(可在https://dev.mysql.com/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');
    Note

    如果您在自定义模式下安装了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 账户接收语句。由于该账户是 fwgrp 配置文件的成员,该配置文件处于 RECORDING 模式,因此防火墙将语句解释为适用于 fwgrp 的规则,并将语句的标准化摘要形式记录到 fwgrp 允许列表中。然后,这些规则将应用于所有属于 fwgrp 的账户。

    Note

    直到 fwgrp 组配置文件在 RECORDING 模式下接收语句,其允许列表为空,这相当于 拒绝所有。 没有语句可以匹配空的允许列表,这将产生以下影响:

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

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

  5. 此时,组配置文件信息被缓存,包括其名称、成员资格和允许列表。要查看这些信息,请查询性能架构防火墙表:

    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` |
    +----------------------------------------------------------------------+
    Note

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

    Important

    在应用程序使用条件下训练防火墙。例如,要确定服务器特征和功能,某个 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,那么使用该连接器来训练防火墙,以便这些初始语句成为关联应用程序的组配置文件的允许列表的一部分。

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

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

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

  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 的训练,请执行以下操作:<|start_header_id|>assistant<|end_header_id|> Let me know when you're ready to translate the next HTML snippet!

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

这样启用了指定账户的额外培训,而无需删除其他组成员。他们可以执行语句,但这些语句不会添加到允许列表中。(请注意,在RECORDING模式下,其他成员可以执行任何语句。)

Note

为了避免在指定账户作为组配置文件的培训账户时出现意外行为,请确保该账户是组的成员。

在额外培训后,将组配置文件设置回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 Enterprise Firewall 允许注册与单个账户对应的配置文件。要使用防火墙账户配置文件保护 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,这也是防火墙所看到的。

    • 因此,用于防火墙操作的账户名称是me@abc.example.org,而不是me@%.example.org

以下过程显示如何使用防火墙注册帐户配置文件,训练防火墙了解该配置文件的可接受语句(其允许列表),并使用配置文件保护 MySQL 免受不可接受语句的执行。

使用管理 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');
    Note

    如果您在自定义模式中安装了 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 模式中,防火墙将语句的标准化摘要形式记录为配置文件允许列表中的规则。

    Note

    直到 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 ?                                         |
    +----------------------------------------------------------------------------+
    Note

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

    Important

    在应用程序使用情况下训练防火墙。例如,要确定服务器特征和功能,某个 MySQL 连接器可能在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,那么使用该连接器来训练防火墙,以便这些初始语句成为关联应用程序的帐户配置文件的一部分。

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

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

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

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

然后,使用账户执行不匹配账户配置文件 allowlist 的语句。在 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,因为 @@version_comment 语句由 mysql 客户端在每次连接使用注册账户时发送,另外还有一个 SHOW TABLES 语句未被阻止在 DETECTING 模式下。

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

MySQL Enterprise Firewall 支持每个应用于单个账户的账户配置文件,也支持每个可以应用于多个账户的组配置文件。组配置文件使得管理变得更容易,当相同的 allowlist 需要应用于多个账户时:而不是为每个账户创建一个账户配置文件并在所有这些配置文件中复制 allowlist,而是创建一个组配置文件并使账户成为其成员。然后,组 allowlist 将应用于所有账户。

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

由于组配置文件提供了更大的灵活性,因此建议所有新的防火墙配置文件都创建为组配置文件。账户配置文件自 MySQL 8.0.26 起弃用,并将在未来 MySQL 版本中删除。对于从已经包含账户配置文件的防火墙安装升级,MySQL Enterprise Firewall 包括一个名为 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 Enterprise Firewall,请对您的系统进行适当的替换。

  2. 通过查询 Information Schema MYSQL_FIREWALL_USERS 表来确定存在的账户配置文件。例如:

    mysql> SELECT USERHOST FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS;
    +-------------------------------+
    | USERHOST                      |
    +-------------------------------+
    | admin@localhost               |
    | local_client@localhost        |
    | remote_client@abc.example.com |
    +-------------------------------+
  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 Enterprise Firewall,请对您的系统进行适当的替换。

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