Documentation Home
MySQL 8.0 参考手册  / 第 6 章 安全  / 6.4 安全组件和插件  / 6.4.7 MySQL 企业防火墙  /  6.4.5.3 使用 MySQL 企业防火墙

6.4.5.3 使用 MySQL 企业防火墙

在使用 MySQL Enterprise Firewall 之前,请按照第 6.4.5.2 节“安装或卸载 MySQL Enterprise Firewall”中提供的说明进行安装。此外,MySQL Enterprise Firewall 不与查询缓存一起工作;如果启用了查询缓存,则将其禁用(请参阅 第 8.10.3.3 节,“查询缓存配置”)。

本节介绍如何使用 SQL 语句配置 MySQL Enterprise Firewall。或者,MySQL Workbench 6.3.4 或更高版本提供用于防火墙控制的图形界面。请参阅 MySQL 企业防火墙接口

启用或禁用防火墙

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

[mysqld]
mysql_firewall_mode=ON

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

也可以在运行时禁用或启用防火墙:

SET GLOBAL mysql_firewall_mode = OFF;
SET GLOBAL mysql_firewall_mode = ON;
分配防火墙权限

安装防火墙后,将适当的权限授予 MySQL 帐户或用于管理它的帐户:

  • 授予系统数据库EXECUTE中防火墙存储过程的权限 。mysql这些可能会调用管理功能,因此存储过程访问也需要这些功能所需的特权。

  • 授予SUPER权限以便可以执行防火墙管理功能。

防火墙概念

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

防火墙配置文件

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

  • 一个许可名单。白名单是一组规则,用于定义配置文件可接受的语句。

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

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

    防火墙支持基于帐户的配置文件,这样每个配置文件都与特定的客户端帐户(客户端用户名和主机名组合)相匹配。例如,您可以注册一个帐户配置文件,其白名单适用于来自 的连接, admin@localhost并注册另一个帐户配置文件,其白名单适用于来自 的连接 myapp@apphost.example.com

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

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

  • 通过为每个配置文件建立白名单来训练防火墙;也就是说,配置文件允许客户端执行的语句类型。

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

    • 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` = ?

通过使用规范化,防火墙白名单可以存储摘要,每个摘要与从客户端收到的许多不同语句相匹配。有关规范化和摘要的更多信息,请参阅第 22.10 节,“性能模式语句摘要”

警告

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

笔记

在 MySQL 5.6.25 之前,MySQL Enterprise Firewall 记录服务器收到的准备好的语句,而不是规范化的摘要。因此,空格、制表符和字母大小写对于将允许列表规则与传入语句进行比较很重要。

配置文件操作模式

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

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

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

  • PROTECTING:在此模式下,配置文件允许或阻止语句执行。防火墙将传入的语句与配置文件白名单进行匹配,仅接受匹配的语句并拒绝不匹配的语句。在 RECORDINGmode 中训练配置文件后,将其切换到 PROTECTINGmode 以强化 MySQL 以防止偏离白名单的语句进行访问。从 MySQL 5.6.25 开始,如果 mysql_firewall_trace 启用了系统变量,防火墙还会将拒绝的语句写入错误日志。

  • DETECTING:此模式检测但不阻止入侵(可疑的语句,因为它们与配置文件白名单中的任何内容都不匹配)。在 DETECTING模式下,防火墙将可疑语句写入错误日志,但在不拒绝访问的情况下接受它们。此模式在 MySQL 5.6.26 及更高版本中可用。

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

笔记

DETECTING在mode 或因为 启用时写入 错误日志的消息 mysql_firewall_trace被写为 Notes,它们是信息消息。为确保此类消息出现在错误日志中并且不被丢弃,请将 log_error_verbosity系统变量的值设置为 3。

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

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

  • 会话帐户与具有相同用户和主机的活动帐户配置文件匹配(如果有的话)。最多有一个这样的帐户资料。

将会话帐户与注册配置文件匹配后,防火墙按如下方式处理每个传入语句:

  • 如果没有适用的配置文件,则防火墙不施加任何限制并接受该声明。

  • 如果有适用的配置文件,则其模式决定语句处理:

    • RECORDING模式下,防火墙将语句添加到配置文件白名单规则中并接受它。

    • PROTECTING模式下,防火墙将语句与配置文件白名单中的规则进行比较。如果匹配,防火墙接受该语句,否则拒绝。从 MySQL 5.6.25 开始,如果 mysql_firewall_trace 启用了系统变量,防火墙还会将拒绝的语句写入错误日志。

    • DETECTING模式下,防火墙检测入侵而不拒绝访问。防火墙接受该语句,但也将其与配置文件白名单相匹配,就像在 PROTECTING模式中一样。如果语句可疑(不匹配),防火墙会将其写入错误日志。

注册防火墙帐户配置文件

MySQL Enterprise Firewall 允许注册与个人帐户相对应的配置文件。要使用防火墙帐户配置文件保护 MySQL 免受来自给定帐户的传入语句,请执行以下步骤:

  1. 注册帐户资料并将其置于 RECORDING模式。

  2. 使用账号连接MySQL服务器,执行学习语句。这会训练帐户配置文件并建立构成配置文件白名单的规则。

  3. 将帐户配置文件切换到 PROTECTING模式。当客户端使用该帐户连接到服务器时,帐户配置文件白名单会限制语句的执行。

  4. 如果需要额外的培训,请再次将帐户配置文件切换到RECORDING模式,使用新的语句模式更新其白名单,然后将其切换回PROTECTING模式。

请遵守这些与防火墙相关的帐户参考指南:

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

    将帐户命名为防火墙操作的单引号字符串的要求意味着您不能使用@ 在用户名中嵌入字符的帐户。

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

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

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

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

以下过程显示如何向防火墙注册帐户配置文件,训练防火墙了解该配置文件(其白名单)可接受的语句,并使用配置文件保护 MySQL 免受帐户执行不可接受的语句。假设示例帐户 fwuser@localhost供访问数据库中表的应用程序使用 sakila(可从 https://mysql.net.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');
  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 ?                                         |
    +----------------------------------------------------------------------------+
    笔记

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

    重要的

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

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

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

    将帐户配置文件退出 RECORDING模式会将其缓存数据同步到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 5.6.25 开始,如果 mysql_firewall_trace 启用了系统变量,防火墙还会将拒绝的语句写入错误日志。例如:

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

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

防火墙帐户配置文件现在已针对该 fwuser@localhost帐户进行了培训。当客户端使用该帐户连接并尝试执行语句时,配置文件保护 MySQL 免受配置文件白名单不匹配的语句的影响。

从 MySQL 5.6.26 开始,可以通过将不匹配的语句记录为可疑而不拒绝访问来检测入侵。首先,将帐户配置文件置于 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 whitelist.
Statement: SHOW TABLES LIKE ? '

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

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

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

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

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

监控防火墙

要评估防火墙活动,请检查其状态变量。例如,在执行前面显示的过程来训练和保护fwuser@localhost帐户后,变量如下所示:

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客户端每次使用注册帐户连接 3 次时@@version_comment 发送的 语句,加上未在模式中阻塞的语句。 SHOW TABLESDETECTING