在使用 MySQL Enterprise 防火墙之前,请按照 第 8.4.7.2 节“安装或卸载 MySQL Enterprise 防火墙” 中提供的说明进行安装。
本节介绍如何使用 SQL 语句配置 MySQL Enterprise 防火墙。或者,MySQL Workbench 6.3.4 或更高版本提供了用于防火墙控制的图形界面。请参阅 MySQL Enterprise 防火墙界面.
要启用或禁用防火墙,请设置 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 Enterprise 防火墙)。
仅在安装防火墙时才能授予 FIREWALL_EXEMPT
、FIREWALL_ADMIN
和 FIREWALL_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 Enterprise 防火墙。
配置文件操作模式
与防火墙注册的每个配置文件都有自己的操作模式,从以下值中选择
OFF
:此模式禁用配置文件。防火墙将其视为不活动并忽略它。RECORDING
:这是防火墙训练模式。从与配置文件匹配的客户端接收到的传入语句被认为对配置文件可接受,并成为其 “指纹。” 防火墙记录每个语句的标准化摘要形式,以了解配置文件可接受的语句模式。每个模式都是一条规则,规则的并集是配置文件允许列表。组配置文件和帐户配置文件之间的区别在于,组配置文件的语句记录可以限于从单个组成员(训练成员)接收到的语句。
PROTECTING
:在此模式下,配置文件允许或阻止语句执行。防火墙将传入语句与配置文件允许列表进行匹配,仅接受匹配的语句,拒绝不匹配的语句。在RECORDING
模式下训练配置文件后,将其切换到PROTECTING
模式以加强 MySQL 防御偏离允许列表的语句访问。如果mysql_firewall_trace
系统变量已启用,防火墙还会将被拒绝的语句写入错误日志。DETECTING
:此模式检测但不会阻止入侵(由于与配置文件允许列表中的任何内容都不匹配而可疑的语句)。在DETECTING
模式下,防火墙会将可疑语句写入错误日志,但会接受它们,而不会拒绝访问。
将配置文件分配给上述任何模式值时,防火墙会在配置文件中存储该模式。防火墙模式设置操作也允许使用 RESET
模式值,但此值不会存储:将配置文件设置为 RESET
模式会导致防火墙删除配置文件的所有规则,并将它的模式设置为 OFF
。
在 DETECTING
模式下或由于启用了 mysql_firewall_trace
而写入错误日志的消息将作为笔记写入,这些笔记是信息消息。要确保此类消息出现在错误日志中并且不会被丢弃,请确保错误日志记录详细程度足以包含信息消息。例如,如果您使用基于优先级的日志过滤,如 第 7.4.2.5 节,“基于优先级的错误日志过滤(log_filter_internal)” 中所述,请将 log_error_verbosity
系统变量设置为 3。
多个配置文件应用时的防火墙语句处理
为简单起见,后面几节描述如何设置配置文件,并从防火墙仅将来自客户端的传入语句与单个配置文件(组配置文件或帐户配置文件)进行匹配的角度进行说明。但防火墙操作可能更复杂
组配置文件可以包含多个帐户作为成员。
一个帐户可以是多个组配置文件的成员。
多个配置文件可以匹配给定的客户端。
以下描述涵盖了防火墙操作的一般情况,即可能有多个配置文件适用于传入语句。
如前所述,MySQL 将每个客户端会话与特定的用户名和主机名组合相关联,称为 会话帐户。防火墙将会话帐户与已注册的配置文件进行匹配,以确定哪些配置文件适用于处理来自会话的传入语句
防火墙会忽略不活动的配置文件(模式为
OFF
的配置文件)。会话帐户会匹配每个包含具有相同用户和主机的成员的活动组配置文件。可能有多个这样的组配置文件。
会话帐户会匹配具有相同用户和主机的活动帐户配置文件(如果有)。最多只有一个这样的帐户配置文件。
换句话说,会话帐户可以匹配 0 个或更多个活动组配置文件,以及 0 个或 1 个活动帐户配置文件。这意味着 0 个、1 个或多个防火墙配置文件适用于给定会话,对于该会话,防火墙会对每个传入语句进行如下处理
如果不存在适用配置文件,防火墙不会施加任何限制并接受该语句。
如果存在适用配置文件,它们的模式将决定语句处理方式。
防火墙会将语句记录到每个处于
RECORDING
模式的适用配置文件的允许列表中。对于处于
DETECTING
模式的每个适用配置文件,防火墙会将语句写入错误日志,前提是该语句可疑(与配置文件允许列表不匹配)。如果至少有一个适用配置文件处于
RECORDING
或DETECTING
模式(这些模式接受所有语句),或者如果语句与至少一个处于PROTECTING
模式的适用配置文件的允许列表匹配,那么防火墙会接受该语句。否则,防火墙会拒绝该语句(如果启用了mysql_firewall_trace
系统变量,则将其写入错误日志)。
了解了这些描述之后,接下来的部分将简化当只有一个组配置文件或一个帐户配置文件适用时的场景,并介绍如何设置每种类型的配置文件。
MySQL Enterprise Firewall 支持注册组配置文件。一个组配置文件可以拥有多个帐户作为其成员。要使用防火墙组配置文件来保护 MySQL 免受来自给定帐户的传入语句的影响,请按照以下步骤操作:
注册组配置文件并将其置于
RECORDING
模式。向组配置文件添加一个成员帐户。
使用成员帐户连接到 MySQL 服务器并执行要学习的语句。这将训练组配置文件并建立构成配置文件允许列表的规则。
向组配置文件添加任何其他要作为组成员的帐户。
将组配置文件切换到
PROTECTING
模式。当客户端使用组配置文件的任何成员帐户连接到服务器时,配置文件允许列表会限制语句执行。如果需要进行其他训练,请再次将组配置文件切换到
RECORDING
模式,使用新的语句模式更新其允许列表,然后将其切换回PROTECTING
模式。
请注意以下与防火墙相关的帐户引用指南。
请注意帐户引用出现的上下文。要为防火墙操作命名一个帐户,请将其指定为一个单引号字符串 (
'
)。这与 MySQL 中用于语句(例如user_name
@host_name
'CREATE USER
和GRANT
)的通常约定不同,在这些语句中,您分别为帐户名的用户名和主机部分加上引号 ('
)。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
。(您可以通过相应调整说明来使用其他数据库。)
如果需要,请创建要作为
fwgrp
组配置文件成员的帐户,并授予它们适当的访问权限。这里展示了其中一个成员的语句(选择适当的密码):CREATE USER 'member1'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON sakila.* TO 'member1'@'localhost';
使用
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');
使用
sp_firewall_group_enlist()
存储过程添加一个初始成员帐户,用于训练组配置文件允许列表。CALL mysql.sp_firewall_group_enlist('fwgrp', 'member1@localhost');
要使用初始成员帐户训练组配置文件,请从服务器主机以
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
成员的帐户。注意在
fwgrp
组配置文件在RECORDING
模式下接收语句之前,其允许列表为空,这等同于 “拒绝所有。” 没有任何语句可以与空允许列表匹配,这将产生以下影响:组配置文件无法切换到
PROTECTING
模式。它会拒绝所有语句,从而有效地阻止作为组成员的帐户执行任何语句。组配置文件可以切换到
DETECTING
模式。在这种情况下,配置文件会接受所有语句,但将其记录为可疑的。
此时,组配置文件信息已缓存,包括其名称、成员资格和允许列表。要查看此信息,请查询 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` | +----------------------------------------------------------------------+
注意The
@@version_comment
规则来自 mysql 客户端在您连接到服务器时自动发送的语句。重要在与应用程序使用情况相匹配的条件下训练防火墙。例如,为了确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,请使用该连接器来训练防火墙。这将使这些初始语句成为与应用程序关联的组配置文件允许列表的一部分。
再次调用
sp_set_firewall_group_mode()
将组配置文件切换到PROTECTING
模式。CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');
重要将组配置文件从
RECORDING
模式切换出去会将缓存的数据同步到提供持久底层存储的防火墙数据库表。如果您不切换正在记录的配置文件的模式,则缓存的数据将不会写入持久存储,并在服务器重启时丢失。防火墙数据库可以是mysql
系统数据库或自定义模式(请参阅 安装 MySQL Enterprise Firewall)。向组配置文件添加任何其他应该成为成员的帐户。
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
帐户训练的配置文件允许列表现在也适用于其他帐户。要验证更新后的组成员资格,请再次查询
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 | +----------+-------------------+
通过使用组中的任何帐户执行一些可接受和不可接受的语句来测试组配置文件与防火墙的兼容性。防火墙会将来自帐户的每个语句与配置文件允许列表进行匹配,并接受或拒绝该语句。
此语句与训练语句不完全相同,但生成与其中一个训练语句相同的规范化语句,因此防火墙会接受它。
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`'
这些日志消息可能有助于识别攻击源,如果有必要的话。
如果需要从组配置文件中删除成员,请使用
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 Enterprise Firewall 允许注册与各个帐户相对应的配置文件。要使用防火墙帐户配置文件来保护 MySQL 免受来自给定帐户的传入语句的影响,请执行以下步骤
注册帐户配置文件并将其置于
RECORDING
模式。使用该帐户连接到 MySQL 服务器并执行要学习的语句。这将训练帐户配置文件并建立构成配置文件允许列表的规则。
将帐户配置文件切换到
PROTECTING
模式。当客户端使用该帐户连接到服务器时,帐户配置文件允许列表将限制语句执行。如果需要进行额外的训练,请再次将帐户配置文件切换到
RECORDING
模式,使用新的语句模式更新其允许列表,然后将其切换回PROTECTING
模式。
请注意以下与防火墙相关的帐户引用指南。
请注意帐户引用出现的上下文。要为防火墙操作命名一个帐户,请将其指定为一个单引号字符串 (
'
)。这与 MySQL 中用于语句(例如user_name
@host_name
'CREATE USER
和GRANT
)的通常约定不同,在这些语句中,您分别为帐户名的用户名和主机部分加上引号 ('
)。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
。(您可以通过相应地调整说明来使用不同的数据库。)
如果需要,请创建用于执行语句的帐户(选择适当的密码),并授予其对
sakila
数据库的权限CREATE USER 'fwuser'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
使用
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');
要训练已注册的帐户配置文件,请从服务器主机以
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
模式。在这种情况下,配置文件接受所有语句,但将其记录为可疑。
此时,帐户配置文件信息已缓存。要查看此信息,请查询
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 ? | +----------------------------------------------------------------------------+
注意The
@@version_comment
规则来自 mysql 客户端在您连接到服务器时自动发送的语句。重要在与应用程序使用相匹配的条件下训练防火墙。例如,要确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常是通过该连接器使用的,那么也使用该连接器来训练防火墙。这使得这些初始语句能够成为与应用程序关联的帐户配置文件的允许列表的一部分。
再次调用
sp_set_firewall_mode()
,这次将帐户配置文件切换到PROTECTING
模式CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'PROTECTING');
重要将帐户配置文件从
RECORDING
模式中切换出来会将其缓存的数据同步到提供持久底层存储的防火墙数据库表中。如果您没有为正在记录的配置文件切换模式,则缓存的数据不会写入持久存储,并在服务器重新启动时丢失。防火墙数据库可以是mysql
系统数据库或自定义模式(请参见安装 MySQL Enterprise Firewall)。通过使用该帐户执行一些可接受和不可接受的语句来测试帐户配置文件。防火墙会将来自该帐户的每个语句与配置文件允许列表进行匹配,并接受或拒绝该语句
此语句与训练语句不完全相同,但生成与其中一个训练语句相同的规范化语句,因此防火墙会接受它。
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 Enterprise Firewall 支持每个都应用于单个帐户的帐户配置文件,以及每个都可应用于多个帐户的组配置文件。当需要将相同的允许列表应用于多个帐户时,组配置文件可以简化管理:与其为每个帐户创建一个帐户配置文件并在所有这些配置文件中复制允许列表,不如创建一个组配置文件并将帐户设为其成员。然后,组允许列表将应用于所有帐户。
具有单个成员帐户的组配置文件在逻辑上等同于该帐户的帐户配置文件,因此可以仅使用组配置文件来管理防火墙,而不是混合使用帐户配置文件和组配置文件。对于新的防火墙安装,这可以通过统一地将新的配置文件创建为组配置文件并避免帐户配置文件来实现。
由于组配置文件提供了更大的灵活性,建议所有新的防火墙配置文件都创建为组配置文件。帐户配置文件已弃用,并且可能会在未来的 MySQL 版本中被删除。对于从已经包含帐户配置文件的防火墙安装进行升级,MySQL Enterprise Firewall 包含一个名为sp_migrate_firewall_user_to_group()
的存储过程,可以帮助您将帐户配置文件转换为组配置文件。要使用它,请以具有FIREWALL_ADMIN
权限的用户身份执行以下过程
运行
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,请为您的系统进行适当的替换。
通过查询 Information Schema
MYSQL_FIREWALL_USERS
表来确定哪些帐户配置文件存在。例如mysql> SELECT USERHOST FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS; +-------------------------------+ | USERHOST | +-------------------------------+ | admin@localhost | | local_client@localhost | | [email protected] | +-------------------------------+
对于上一步识别的每个帐户配置文件,将其转换为组配置文件。如有必要,请将
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
模式,并且组配置文件不能已经存在。生成的组配置文件将命名帐户作为其唯一的入列成员,该成员也被设置为组训练帐户。组配置文件操作模式取自帐户配置文件操作模式。(可选)删除
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()
的更多详细信息,请参见防火墙杂项存储过程。