MySQL企业版之Firewall(SQL防火墙)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: MySQL企业版之Firewall(SQL防火墙)

1. 关于Firewall插件

Friewall是MySQL企业版非常不错的功能插件之一,启用Firewall功能后,SQL的执行流程见下图示意:

image.png

2. Firewall插件的工作方式

Firewall插件的工作机制大概是这样的:

0.将某个账号Register(注册)到Firewall插件中,未注册的账号将不会被Firewall插件保护。

1.先将Firewall插件设置 recording(记录)模式,将各种SQL格式化/模式化之后,形成各种不同的SQL fingerprint(指纹)。例如下面的两条SQL,都会被格式化成一条:

# 原始SQL
a) SELECT * FROM t1 WHERE c1 = 1;
b) SELECT * FROM t1 WEHRE c1 = 1024;

# 格式化之后的SQL
SELECT * FROM t1 WHERE c1 = ?;

备注:在这个过程中,如果总有超长SQL的话,需要加大参数 max_digest_length 的设置,其默认值是1024。

2.Firewall插件会学习上述SQL,形成一个白名单。

3.经过一段时间的训练后,可以将Firewall插件工作模式切换为 protecting(保护)模式,开始工作。这时候就能自动判断有哪些SQL可能是恶意的,会被自动拒绝,并且记录到日志中,如果启用参数 mysql_firewall_trace的话。

4.如果还发生个别SQL被拒绝的情况,则可以将插件切换回 recording(记录)模式,继续学习训练一段时间再切换到工作状态。

5.此外,还有一种工作模式是detecting(探测),在这个模式下,符合白名单的会被放过执行,而其他SQL则会被记录到日志中,但并不会被拒绝执行,这就相当于正式开始工作前的灰度测试模式了。

简言之,就是在业务账号对外正式开放前,先自行模拟各种正常业务请求,使之完成前期必要的学习,正式上线后再开启保护模式。因为外网生产环境中坏人太多,任意时候都有可能有坏蛋提交各种恶意破坏的请求。

3. Firewall插件测试

接下来我们做个简单的测试场景。

首先,先尝试将一个新账号直接设置为 protecting 模式,这时候该账号还未学习任何规则,因此所有的SQL应该都会被拒绝才对。

[root@yejr.run]>CALL mysql.sp_set_firewall_mode('yejr@%', 'PROTECTING');

+-------------------------------------------------------------------------+
| result |
+-------------------------------------------------------------------------+
| ERROR: PROTECTING mode requested for yejr@% but the whitelist is empty. |
+-------------------------------------------------------------------------+

嗯,看来这个插件还挺聪明的,发现规则是空的,直接不让设置了,要不然可能会害的DBA直接下岗走人了吧,哈哈。还是先设置为 recording 模式吧。

[root@yejr.run]>CALL mysql.sp_set_firewall_mode('yejr@%', 'recording');
+-----------------------------------------------+
| read_firewall_whitelist(arg_userhost,FW.rule) |
+-----------------------------------------------+
| Imported users: 0
Imported rules: 0
|
+-----------------------------------------------+
1 row in set (0.01 sec)

# 手动查询 mysql.firewall_users 表确认
[root@yejr.run]>select * from mysql.firewall_users;
+----------+-----------+
| USERHOST | MODE |
+----------+-----------+
| yejr@% | RECORDING |
+----------+-----------+
1 row in set (0.00 sec)

设置成功。

然后用这个新账号连接MySQL,执行一些合规的SQL操作后,再查看白名单规则表:

[root@yejr.run]>select * from mysql.firewall_whitelist;
+----------+--------------------------------------------------------+----+
| USERHOST | RULE | ID |
+----------+--------------------------------------------------------+----+
| yejr@% | SHOW CREATE TABLE `t1` | 8 |
| yejr@% | SELECT * FROM `t1` | 9 |
| yejr@% | SELECT * FROM `t1` WHERE `id` >= ? | 10 |
| yejr@% | SELECT FROM `t1` WHERE `id` = `rand` ( ) ? | 11 |
| yejr@% | SELECT FROM `t1` WHERE `id` = `rand` ( ) ? LIMIT ? | 12 |
| yejr@% | SELECT * FROM `t1` WHERE `c1` >= ? | 13 |
+----------+--------------------------------------------------------+----+

再将该账号修改为 PROTECTING 模式:

[root@yejr.run]>CALL mysql.sp_set_firewall_mode('yejr@%', 'PROTECTING');
Query OK, 6 rows affected (0.01 sec)

执行一些不合规的SQL后,看怎么报错的。

[yejr@yejr.run] [test]>select * from t1 order by rand() limit 1;
ERROR 1045 (28000): Statement was blocked by Firewall

error log中也记录了相应的行为:

2020-06-09T09:50:38.286878Z 26 [Note] [MY-011192] [Server] Plugin MYSQL_FIREWALL reported: 'ACCESS DENIED for 'yejr@%'. Reason: No match in whitelist. Statement: SELECT * FROM `t1` ORDER BY `rand` ( ) LIMIT ?'

再查看几个相关的全局状态参数:

[root@yejr.run] [mysql]>show global status like '%firewall%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Firewall_access_denied | 10 | #拒绝次数
| Firewall_access_granted | 11 | #通过次数
| Firewall_access_suspicious | 9 | #在DETECTING模式下不匹配白名单的次数
| Firewall_cached_entries | 6 | #在cache中的白名单数量

想要关闭该账号的Firewall规则,执行下面的指令即可:

[root@yejr.run] [mysql]>call mysql.sp_set_firewall_mode('yejr@%', 'RESET');

或者只是简单地设置为 OFF 也可以:

二者的区别在于,设置为 RESET 时,除了关闭Firewall保护,同时也会将该账号之前训练学习的白名单全部清空,这样下次再想采用Firewall保护就需要重头开始了,除非再也不用了,否则不建议这么做。当已经对一个账号启用Firewall保护后,此时有新增业务SQL不在白名单中,除了将模式改回 RECORDINGDETECTING 之外,其实还可以手动往 mysql.firewall_whitelist 表中插入格式化之后的SQL,再刷新使之生效即可,例如:

[root@yejr.run] [mysql]>call mysql.sp_set_firewall_mode('yejr@%', 'OFF');

4. 总结

简单测试下来,我认为Firewall插件至少有几个地方可以更完善:

1.对SQL进行格式化时,不支持正则匹配模式,建议增加。

2.设置RECORDING模式测试期间,我执行一个SQL后,又手动执行CTRL+C终止,结果记录了一条KILL QUERY ? 的规则,这个规则就不建议记录了。

3.存储过程 mysql.sp_reload_firewall_rules() 可以增加一个参数表示重载规则后,是否要顺便设置账号的规则,例如 CALL mysql.sp_reload_firewall_rules('yejr@%', 'PROTECTING') 表示重载完规则后,顺便将该账号设置为 PROTECTING 模式。

总的来说,Firewall插件工作方式还是比较简单的,直观感觉就是对规则的学习比较初级,真正在线上生产环境启用的话,可能需要记录大量的规则,这也势必会造成性能的下降,以后再做个性能测试吧。

更多关于Firewall插件资料请查看官方手册。

最后亲切友情提醒:MySQL企业版下载后只能试用一个月,试用完毕后记得删除卸载哟,土豪的话直接无脑付费即可哟



            </div>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
SQL
记一次不常见到主从延迟问题
Slave_SQL_Running_State: Waiting for dependent transaction to commit 导致的主从延迟
8286 1
|
关系型数据库 MySQL Linux
【Linux环境】centos安装mysql5.7.26报 ./mysqld: error while loading shared libraries: libaio.so.1: cannot op
【Linux环境】centos安装mysql5.7.26报 ./mysqld: error while loading shared libraries: libaio.so.1: cannot op
1364 0
|
安全 Java 开发者
Java一分钟之-Spring Cloud Netflix Eureka:服务注册与发现
【6月更文挑战第8天】Spring Cloud Eureka是微服务架构的关键,提供服务注册与发现功能。本文讲解Eureka工作原理、配置、常见问题及解决方案。Eureka包含Server(管理服务状态)和Client(注册服务实例并发现服务)。快速入门包括启动Eureka Server和创建Eureka Client。常见问题涉及服务注册不上、服务下线和客户端注册信息不准确,可通过检查网络、理解自我保护机制和配置元数据解决。此外,文中还提及健康检查、安全配置和集群部署等高级实践,以增强系统健壮性和扩展性。
515 8
|
数据采集 存储 JavaScript
Dynamic Website 爬虫:应对动态内容与 JavaScript 渲染挑战
本文深入探讨了如何设计针对动态网站的爬虫,以采集 WIPO Brand Database 中的专利和技术信息。文章详细介绍了动态网站的挑战,包括 JavaScript 渲染、反爬虫机制和异步加载,并提出了解决方案,如使用 Selenium 模拟浏览器、代理 IP 技术和 API 抓取。最后,通过具体代码示例展示了如何实现这些技术手段。
767 0
|
Oracle 网络协议 关系型数据库
Oracle DataGuard主备切换之自动切换
Oracle DataGuard主备切换之自动切换
755 2
IDEA中返回上一步和下一步快捷键失效【Ctrl+Alt+左箭头】
这篇文章提供了解决IntelliJ IDEA中"返回上一步"和"下一步"快捷键失效的方法,通常是因为与其他软件的快捷键发生冲突,解决方法是更改快捷键设置。
|
SQL Oracle 关系型数据库
Oracle之如何将分隔数据转换为IN列表
Oracle之如何将分隔数据转换为IN列表
424 1
|
关系型数据库 数据库 文件存储
PG技术大讲堂 - 第12讲:PostgreSQL wal作用与管理
PostgreSQL从小白到专家,技术大讲堂 - 第12讲:PostgreSQL wal作用与管理
422 1
|
SQL Oracle 关系型数据库
Oracle 等待事件研究:SQL*Net break/reset to client
SQL*Net break/reset to client事件是一个容易被误解的事件,这个事件看起来和网络有关,但实际上大多数情况下这个事件与网络无关。
1235 0
Oracle 等待事件研究:SQL*Net break/reset to client
|
数据可视化 Java API
spring boot 下swagger2 的使用
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。 swagger 官方Demo供参考 https://petstore.swagger.io/ swagger注解 swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。 API详细说明 @Api(tags = "收付费方式变更") 常用 @ApiOperation("获取用户列表") 常用 @ApiParam(v
403 0
spring boot 下swagger2 的使用