代码改变世界

使用连接控制插件保护MySQL连接安全

  abce  阅读(766)  评论(0编辑  收藏  举报

connection_control插件是在MySQL 8.0中引入,并支持向后移植到MySQL 5.7和MySQL 5.6。

在一定次数的连续登录失败尝试后,连接控制插件允许管理员增加服务器对连接的响应延迟。没有得到服务器的响应之前,未经授权的用户或客户端不知道密码是否正确。因此,如果攻击者通过生成多个连接请求来攻击服务器,那么这些连接必须处于活动状态,直到服务器响应为止。引入延迟使攻击者更难攻击,因为现在资源被用于确保连接请求处于活动状态。这种技术可以减缓针对MySQL用户帐户的暴力攻击。

连接控制插件库包含两个插件:

1.connection_control:检查进来的连接尝试,根据需要增加延迟响应。

2.connection_control_failed_login_attempts:information_schema中增加了一个表,记录失败连接的具体信息。

 

安装连接控制插件

运行时安装

1
2
3
4
>install plugin connection_control soname 'connection_control.so';
Query OK, 0 rows affected (0.01 sec)
>install plugin connection_control_failed_login_attempts soname 'connection_control.so';
Query OK, 0 rows affected (0.01 sec)

也可以在配置文件中加入连接控制插件

1
2
3
4
[mysqld]
plugin-load-add=connection_control.so           #加载connection_control.so库
connection-control=FORCE_PLUS_PERMANENT         #使用连接控制插件,如果初始化失败,MySQL启动会失败
connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT   #使用connection-control-failed-login-attempts插件,如果初始化失败,MySQL启动会失败

检查安装结果

1
2
3
4
5
6
7
8
>select plugin_name, plugin_status from information_schema.plugins where plugin_name like '%connection%';
+------------------------------------------+---------------+
| plugin_name                              | plugin_status |
+------------------------------------------+---------------+
| CONNECTION_CONTROL                       | ACTIVE        |
| CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | ACTIVE        |
+------------------------------------------+---------------+
2 rows in set (0.00 sec)

 

配置连接控制的阈值

现在,使用这些服务器参数为失败的连接尝试配置服务器响应延迟。我们将尝试连续失败连接的阈值设置为3,并添加至少1秒的连接延迟。

1
2
3
> set global connection_control_failed_connections_threshold = 3;#在增加延迟响应之前,允许连接失败尝试的次数;0表示禁用该属性
set global connection_control_min_connection_delay = 1000;  #延迟响应的最小毫秒阈值
set global connection_control_max_connection_delay = 90000;#延迟响应的最大毫秒阈值

持久化配置:

1
2
3
SET PERSIST connection_control_failed_connections_threshold = 3;
SET PERSIST connection_control_min_connection_delay = 1000;
SET PERSIST connection_control_max_connection_delay = 90000;

也可以在配置文件中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
connection_control_failed_connections_threshold=3
connection_control_min_connection_delay=1000
connection_control_max_connection_delay=90000
 
>show variables like '%connection_control%';
+-------------------------------------------------+-------+
| Variable_name                                   | Value |
+-------------------------------------------------+-------+
| connection_control_failed_connections_threshold | 3     |
| connection_control_max_connection_delay         | 90000 |
| connection_control_min_connection_delay         | 1000  |
+-------------------------------------------------+-------+
3 rows in set (0.00 sec)

 

测试过程

第一个终端:

1
2
3
4
5
6
7
8
9
10
11
12
>select * from information_schema.connection_control_failed_login_attempts;
Empty set (0.00 sec)
 
>show global status like 'connection_control_%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| Connection_control_delay_generated | 0     |
+------------------------------------+-------+
1 row in set (0.01 sec)
 
>

目前是没有延迟响应产生。

在第二个终端,尝试使用错误的密码进行登录:

查看mysql中的进程,可以看到,连接的状态是"Waiting in connection_control plugin"

1
2
3
4
5
6
7
8
>show processlist;
+----+-----------------+-----------+------+---------+------+--------------------------------------+------------------+---------+-----------+---------------+
| Id | User            | Host      | db   | Command | Time | State                                | Info             | Time_ms | Rows_sent | Rows_examined |
+----+-----------------+-----------+------+---------+------+--------------------------------------+------------------+---------+-----------+---------------+
|  5 | event_scheduler | localhost | NULL | Daemon  |  323 | Waiting on empty queue               | NULL             |  323577 |         0 |             0 |
|  8 | root            | localhost | NULL | Query   |    0 | init                                 | show processlist |       0 |         0 |             0 |
| 27 | root            | localhost | NULL | Connect |    1 | Waiting in connection_control plugin | NULL             |    1935 |         0 |             0 |
+----+-----------------+-----------+------+---------+------+--------------------------------------+------------------+---------+-----------+---------------+

三个连接之后的连接,开始经过一段时间的响应延迟。直至尝试结束。每个尝试的延迟都会增加一秒。

第二个终端的脚本运行结束后,回到第一个终端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>show global status like 'connection_control_%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| Connection_control_delay_generated | 57    |
+------------------------------------+-------+
1 row in set (0.00 sec)
>select failed_attempts from information_schema.connection_control_failed_login_attempts;
+-----------------+
| failed_attempts |
+-----------------+
|              60 |
+-----------------+
1 row in set (0.00 sec)

多次错误尝试失败后,如果一个正确的密码尝试连接进来,因为之前已经有N个尝试失败,正确的连接也需要等待N秒的延迟。

1
2
3
4
5
6
7
8
9
# date; mysql -uroot -p'xxx' -e "select now();";date
Thu 18 May 2023 02:25:09 PM CST
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------+
| now()               |
+---------------------+
| 2023-05-18 14:26:08 |
+---------------------+
Thu 18 May 2023 02:26:08 PM CST

接下来正确的连接就不用延迟响应了:

1
2
3
4
5
6
7
8
9
# date; mysql -uroot -p'xxx' -e "select now();";date
Thu 18 May 2023 02:27:07 PM CST
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------+
| now()               |
+---------------------+
| 2023-05-18 14:27:07 |
+---------------------+
Thu 18 May 2023 02:27:07 PM CST

 

找出是哪个用户在尝试暴力破解登录

1
2
3
4
5
6
7
>select * from information_schema.connection_control_failed_login_attempts;
+--------------------+-----------------+
| USERHOST           | FAILED_ATTEMPTS |
+--------------------+-----------------+
| 'root'@'localhost' |              60 |
+--------------------+-----------------+
1 row in set (0.01 sec)

 

重新设置阈值

如果想重新设置这些计数器,重新给connection_control_failed_connections_threshold设置一个值即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
>SET GLOBAL connection_control_failed_connections_threshold = 3;
Query OK, 0 rows affected (0.00 sec)
 
>select * from information_schema.connection_control_failed_login_attempts;
Empty set (0.00 sec)
 
>show global status like 'connection_control_%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| Connection_control_delay_generated | 0     |
+------------------------------------+-------+
1 row in set (0.00 sec)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2022-05-18 SQL Server AlwaysOn的监听
2022-05-18 SQLServer AlwaysON修改可用性组的监听端口
2022-05-18 SQLServer修改Availability Group Endpoint的属主
2022-05-18 SQLServer将数据库置为只读
点击右上角即可分享
微信分享提示