微信搜索“coder-home”或扫一扫下面的二维码,关注公众号,
第一时间了解更多干货分享,还有各类视频教程资源。扫描它,带走我

需求背景
安装插件Connection-Control
通过命令直接安装
通过配置文件安装
永久启用Connection-Control
查看已经安装的插件
查看插件的安装目录
安装Connection-Control插件
配置锁定用户的条件
了解配置参数
配置触发条件
验证效果
总结
需求背景
为了进一步保护我们的MySQL
数据库不被恶意攻击,我们可以给MySQL的登录用户增加一个保护的功能:当某一个用户输入错误密码的次数超过指定的值后,禁止这个用户再次马上发起连接请求,这个禁止的时间长短可以灵活配置,不让其再次尝试登录,从而避免用户的密码被暴力的破解。
我自己首先的疑惑是:MySQL
支持这样的功能吗?
答案是肯定的,MySQL
官方文档中有这样一段描述:
As of MySQL 5.7.17, MySQL Server includes a plugin library that enables administrators to introduce an increasing delay in server response to connection attempts after a configurable number of consecutive failed attempts. This capability provides a deterrent that slows down brute force attacks against MySQL user accounts. The plugin library contains two plugins:
CONNECTION_CONTROL
checks incoming connection attempts and adds a delay to server responses as necessary. This plugin also exposes system variables that enable its operation to be configured and a status variable that provides rudimentary monitoring information.The
CONNECTION_CONTROL
plugin uses the audit plugin interface (see Writing Audit Plugins). To collect information, it subscribes to theMYSQL_AUDIT_CONNECTION_CLASSMASK
event class, and processesMYSQL_AUDIT_CONNECTION_CONNECT
andMYSQL_AUDIT_CONNECTION_CHANGE_USER
subevents to check whether the server should introduce a delay before responding to connection attempts.CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
implements anINFORMATION_SCHEMA
table that exposes more detailed monitoring information for failed connection attempts.
从上面的描述中,我们可以看出这种功能在安装完成MySQL
之后是不会默认就开启的,并且这种功能是以一种插件的方式来安装到MySQL
中的。
注意:上面的两个插件CONNECTION_CONTROL
和CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
都需要安装才可以实现前面我们描述的需求,两者不可或缺。
所以,我们如果想要开启这个功能,前提是我们先在我们的MySQL
服务中安装这个功能插件,然后在开启这个功能。接下里然我们一起安装并且启用这个插件吧。
安装插件Connection-Control
查看已经安装的插件
在开始安装我们的Connection-Control
插件之前,我们先看下我们的MySQL
默认是安装了哪些插件。我们可以使用如下两个中的任何一个命令查看已经安装的插件有哪些。
第一个命令是显示简单的插件信息,第二个命令可以查看更详细的插件信息。
show plugins;
select * from information_schema.plugins;;
示例如下:
mysql> show plugins;
+----------------------------+----------+--------------------+---------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+---------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| sha256_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ngram | ACTIVE | FTPARSER | NULL | GPL |
+----------------------------+----------+--------------------+---------+---------+
44 rows in set (0.01 sec)
mysql>
mysql> select plugin_name, plugin_status, plugin_type, plugin_library load_option from information_schema.plugins;
+----------------------------+---------------+--------------------+-------------+
| plugin_name | plugin_status | plugin_type | load_option |
+----------------------------+---------------+--------------------+-------------+
| binlog | ACTIVE | STORAGE ENGINE | NULL |
| mysql_native_password | ACTIVE | AUTHENTICATION | NULL |
| sha256_password | ACTIVE | AUTHENTICATION | NULL |
| CSV | ACTIVE | STORAGE ENGINE | NULL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL |
| INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL |
| INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL |
| PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL |
| FEDERATED | DISABLED | STORAGE ENGINE | NULL |
| partition | ACTIVE | STORAGE ENGINE | NULL |
| ngram | ACTIVE | FTPARSER | NULL |
+----------------------------+---------------+--------------------+-------------+
44 rows in set (0.00 sec)
mysql>
从上面的结果可以看出,像mysql_native_password
、sha256_password
这些关于MySQL
用户密码的插件已经是默认安装并启用的。另外,我们都知道MySQL
整体架构分为服务层和存储引擎层,而存储引擎是以插件的方式来安装在MySQL
中的。从上面的结果中也可以印证这一个概念,上面我们看到有各种存储引擎,像:CSV
、InnoDB
、MEMORY
、MyISAM
、ARCHIVE
等存储引擎都在插件列表中。
查看插件的安装目录
我们安装了插件之后,这些插件要存在于MySQL
数据库服务器上面的某个目录下面,这样这些插件才能工作,那么安装这些被插件都放在哪里了呢?如果你也有这个好奇的想法,可以通过如下的命令来查看plugin_dir
的值即可:
mysql> show variables like 'plugin_dir';
+---------------+------------------------+
| Variable_name | Value |
+---------------+------------------------+
| plugin_dir | usr/lib/mysql/plugin/ |
+---------------+------------------------+
1 row in set (0.01 sec)
mysql>
我们也可以到这个plugin_dir
目录下面看下到底有哪些东西。在Linux
服务上面进入plugin_dir
,显示如下:
root@master1:/usr/lib/mysql/plugin# ls -lstr
total 6752
28 -rw-r--r-- 1 root root 27624 Jun 2 19:30 version_token.so
32 -rw-r--r-- 1 root root 32152 Jun 2 19:30 validate_password.so
20 -rw-r--r-- 1 root root 19160 Jun 2 19:30 semisync_slave.so
64 -rw-r--r-- 1 root root 62000 Jun 2 19:30 semisync_master.so
60 -rw-r--r-- 1 root root 60904 Jun 2 19:30 rewriter.so
1816 -rw-r--r-- 1 root root 1855976 Jun 2 19:30 mysqlx.so
16 -rw-r--r-- 1 root root 14512 Jun 2 19:30 mysql_no_login.so
16 -rw-r--r-- 1 root root 14968 Jun 2 19:30 mypluglib.so
16 -rw-r--r-- 1 root root 14288 Jun 2 19:30 locking_service.so
16 -rw-r--r-- 1 root root 15096 Jun 2 19:30 libpluginmecab.so
280 -rw-r--r-- 1 root root 283416 Jun 2 19:30 libmemcached.so
24 -rw-r--r-- 1 root root 22944 Jun 2 19:30 keyring_udf.so
84 -rw-r--r-- 1 root root 85704 Jun 2 19:30 keyring_file.so
108 -rw-r--r-- 1 root root 110080 Jun 2 19:30 innodb_engine.so
4040 -rw-r--r-- 1 root root 4135568 Jun 2 19:30 group_replication.so
48 -rw-r--r-- 1 root root 48920 Jun 2 19:30 connection_control.so
36 -rw-r--r-- 1 root root 35416 Jun 2 19:30 authentication_ldap_sasl_client.so
16 -rw-r--r-- 1 root root 14616 Jun 2 19:30 auth_socket.so
28 -rw-r--r-- 1 root root 25488 Jun 2 19:30 adt_null.so
4 drwxr-xr-x 2 root root 4096 Oct 13 16:03 debug
root@master1:/usr/lib/mysql/plugin#
安装Connection-Control插件
安装后的插件的后缀名称根据平台的不同而不同,Unix/Linux
系统下,插件安装后的文件会以.so
的文件存放于plugin_dir
目录下面,而在Windows
平台下面,则会有.dll
的文件存在于plugin_dir
目录下面。
我们在Linux
服务器上面来安装,那么Connection-Control
插件文件名称就是connection_control.so
。
通过命令直接安装
如果我们想在不停止MySQL
对外提供访问服务的前提下来安装插件,此时,我们可以使用下面的SQL
命令来安装我们需要的插件。
INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
同理,卸载这两个插件的命令如下所示:
UNINSTALL PLUGIN CONNECTION_CONTROL;
UNINSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS;
安装和卸载的示例如下:
mysql> INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
Query OK, 0 rows affected (0.22 sec)
mysql> INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
Query OK, 0 rows affected (0.05 sec)
mysql> uninstall plugin CONNECTION_CONTROL;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> uninstall plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS;
Query OK, 0 rows affected (0.00 sec)
mysql>
此时我们再去information_schema.plugins
表中查看一下已经安装的插件有哪些,结果如下:
mysql> select plugin_name, plugin_status, plugin_type, plugin_library load_option from information_schema.plugins where plugin_name like '%CONTROL%' \G
*************************** 1. row ***************************
plugin_name: CONNECTION_CONTROL
plugin_status: ACTIVE
plugin_type: AUDIT
load_option: connection_control.so
*************************** 2. row ***************************
plugin_name: CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
plugin_status: ACTIVE
plugin_type: INFORMATION SCHEMA
load_option: connection_control.so
2 rows in set (0.01 sec)
mysql>
从上面的结果中可以看出已经包含了我们要安装的两个插件:CONNECTION_CONTROL
和CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
。此时说明我们已经安装成功了Connection-Control
插件。
通过配置文件安装
除了直接通过命令安装Connection-Control
插件之外,我们还可以在MySQL
的配置文件my.cnf
中配置启动选项。这样,MySQL
在启动的时候就可以自动加载Connection-Control
插件了。
在MySQL
的my.cnf
配置文件中增加如下选项:
[mysqld]
plugin-load-add=connection_control.so
注意:修改完上面的配置文件之后,想要使此次的修改生效,则需要重新启动MySQL
服务。具体重启MySQL
服务的方式参考如下命令:
systemctl stop mysqld.service
systemctl start mysqld.service
systemctl restart mysqld.service
永久启用Connection-Control
通过上面的install plugin
的命令或者修改my.cnf
配置文件来安装Connection-Control
插件之后,在MySQL
运行的过程中,可以通过uninstall plugin
的命令删除安装的插件。
为了避免插件的功能被删除,我们可以在MySQL
的my.cnf
配置文件中声明强制启用``Connection-Control`插件,从而避免被删除。
[mysqld]
plugin-load-add=connection_control.so
connection-control=FORCE_PLUS_PERMANENT
connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT
当我们增加了上面两行配置之后,再次尝试卸载Connection-Control
插件的时候,会出现如下的错误提示:
mysql> uninstall plugin CONNECTION_CONTROL;
ERROR 1702 (HY000): Plugin 'CONNECTION_CONTROL' is force_plus_permanent and can not be unloaded
mysql> uninstall plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS;
ERROR 1702 (HY000): Plugin 'CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS' is force_plus_permanent and can not be unloaded
mysql>
配置锁定用户的条件
安装启用Connection-Control
功能之后,接下来我们开始配置用户在连接失败多少次之后,禁止用户登录。
了解配置参数
在配置之前,我们先来了解一下下面这几个参数。
connection_control_failed_connections_threshold:
登陆失败次数限制。
当有任何一次登录成功后,累计失败的值将重新从0开始累计统计。
如果这个值设置为0,则表示禁用统计失败的功能。
connection_control_min_connection_delay:查过失败次数后,再登录的时候,最小的重试间隔,单位为毫秒。
connection_control_max_connection_delay:查过失败次数后,再登录的时候,重大的重试间隔,单位为毫秒。取值范围为[1000,2147483647],即为[1秒,24.8天]。
注意:在配置min
和max
的delay
的值的时候,要时刻保证min<=max
。比如现在的min
和max
的值为[1000,2000],如果你想把它们两个的值设置为[3000,5000],我们不能先修改min
的值为3000,在修改max的值为5000
。因为此时max的值为2000,我们是不能把min
的直接设置为3000的。应该先修改max
的值为5000,然后再修改min
的值为3000
配置触发条件
这里的配置也可以在配置文件my.cnf
中配置,也可以在MySQL的命令终端中使用set global key=value
的方式来配置。
在MySQL的配置文件中配置如下:
[mysqld]
# 最多连续4次错误登录
connection_control_failed_connections_threshold=4
# 休眠2000毫秒后再次尝试建立连接
connection_control_min_connection_delay=2000在MySQL命令行终端中配置如下:
SET GLOBAL connection_control_failed_connections_threshold = 3;
SET GLOBAL connection_control_min_connection_delay = 5000;
注意:如果配置文件和命令行中都设置的对应的值,那么命令行总的设置将会覆盖配置文件中的设置。但是在MySQL服务重启之后,就会再次以配置文件中的设置为准,上次在命令行终端中配置的值将会被舍弃。
验证效果
示例如下:

总结
通过上面的示例我们可以看到,Connection-Control
插件对连续失败登录控制有效果的,这样做可以避免了大量的、非法连接攻击,避免了暴力破击我们的MySQL
数据库密码的可能性。增加了数据库的安全系数。
微信搜索“coder-home”或扫一扫下面的二维码,关注公众号,
第一时间了解更多干货分享,还有各类视频教程资源。扫描它,带走我





