笑迎人生 發表於 2025-9-15 17:13:00

MySQL如何统计/监控MySQL用户登录失败?

<p>在MySQL数据库中,如何统计/监控MySQL用户登陆失败的次数呢? 下面是我的一些探索与总结,如有不足或疏漏,欢迎指正。</p>
<h1 id="错误日志监控统计">错误日志监控统计</h1>
<p>首先,要设置错误日志记录告警信息的级别,</p>
<p>MySQL 5.5,5.6,5.7.2之前设置系统变量log_warnings</p>
<pre><code class="language-bash">show variables like 'log_warnings';
set global log_warnings=3;
</code></pre>
<p>有些MySQL版本可以将系统变量log_warnings=2.</p>
<p>MySQL 5.7.2 ~ 8.*设置系统变量log_error_verbosity</p>
<pre><code class="language-bash">show variables like 'log_error_verbosity';
set global log_error_verbosity=3;
</code></pre>
<p>一般设置系统变量log_error_verbosity的值为3后,就能在错误日志中记录这些登录失败的相关信息/记录</p>
<pre><code class="language-bash"> Access denied for user '****'@'***.***.***.***' (using password : NO)
</code></pre>
<p>具体案例如下所示</p>
<pre><code class="language-bash">2025-08-01T08:26:58.638998+08:00 364 Access denied for user 'kkk'@'localhost' (using password: YES)
</code></pre>
<p>对于错误日志中的登录失败的信息,最好通过脚本去监控,我这边会通过mysql_log_maint_monitor.sh脚本去监控MySQL错误日志的各种错误信息.所以一旦出现用户登录数据库失败的情况,5分钟(作业5分钟运行一次)就能收到告警.</p>
<p>你也可以使用下面脚本手工统计账号登录失败信息:</p>
<pre><code class="language-bash">grep 'Access denied for user'/data/mysql/logs/mysql_error.log | wc -l
grep 'Access denied for user'/data/mysql/logs/mysql_error.log | grep -oE "user [^ ]+" | sort | uniq -c

或者

grep '\'/data/mysql/logs/mysql_error.log | wc -l
grep '\'/data/mysql/logs/mysql_error.log | grep -oE "user [^ ]+" | sort | uniq -c
</code></pre>
<h1 id="connection-control插件监控">Connection Control插件监控</h1>
<p>使用Connection Control插件监控的前提是安装这个插件,如下所示</p>
<pre><code class="language-SQL">INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
</code></pre>
<p>参数是默认值,如下所示</p>
<pre><code>mysql&gt;show variables like '%connection_control%';
+-------------------------------------------------+------------+
| Variable_name                                 | Value      |
+-------------------------------------------------+------------+
| connection_control_failed_connections_threshold | 3          |
| connection_control_max_connection_delay         | 2147483647 |
| connection_control_min_connection_delay         | 1000       |
+-------------------------------------------------+------------+
3 rows in set (0.00 sec)

mysql&gt;
</code></pre>
<p>其中,</p>
<p>connection_control_failed_connections_threshold:触发延迟的失败尝试次数阈值,默认为 3。</p>
<p>connection_control_min_connection_delay:首次触发延迟时的最小延迟时间,默认1000毫秒,即 1 秒。</p>
<p>connection_control_max_connection_delay:最大延迟时间,默认 2147483647 毫秒。</p>
<p>下面创建一个账号test进行测试</p>
<pre><code>mysql&gt; select version();
+-----------+
| version() |
+-----------+
| 8.0.35    |
+-----------+
1 row in set (0.00 sec)

mysql&gt; create user 'test'@'%' identified by random password;
+------+------+----------------------+-------------+
| user | host | generated password   | auth_factor |
+------+------+----------------------+-------------+
| test | %    | 68xX:d:6N2uU(EeKg]Sg |         1 |
+------+------+----------------------+-------------+
1 row in set (0.02 sec)

mysql&gt;

# 授予相关权限,此处略过
.......................
</code></pre>
<p>找一台测试服务器,使用错误的密码尝试连接数据库,如下所示</p>
<pre><code class="language-bash">$ time mysql -h 10.160.2.36-u test -pk1213423
mysql: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'test'@'10.160.2.53' (using password: YES)

real    0m0.028s
user    0m0.007s
sys   0m0.007s
</code></pre>
<p>此时,你就能从CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS表中看到相关账号登陆失败的尝试信息,如下所示:</p>
<pre><code class="language-SQL">mysql&gt; select * from information_schema.CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS;
+------------+-----------------+
| USERHOST   | FAILED_ATTEMPTS |
+------------+-----------------+
| 'test'@'%' |               1 |
+------------+-----------------+
1 row in set (0.01 sec)
</code></pre>
<p>但是这种方法有一个弊端,有时候只能看到哪一个账号登录失败的次数,无法判别什么时间点,来自哪一个IP,而错误日志则能获取更多信息.<br>
如下所示:</p>
<pre><code class="language-bash">2025-08-21T08:58:16.585600+08:00 633747 Access denied for user 'test'@'10.160.2.53' (using password: YES)
</code></pre>
<p>从错误日志,我们能知道的信息,2025-08-21T08:58:16.585600+08:00这个时间点,10.160.2.53这个IP使用test登录数据库是被拒绝了.</p>
<h1 id="审计插件">审计插件</h1>
<p>另外一件大杀器就是通过审计插件来实现, 这个是更方便、省心的方法. 这里不展开介绍,有兴趣的可以自己了解. 主要是没有太多可以说的.只需从从审计日志或记录中找到记录并告警.</p>


</div>
<div id="MySignature" role="contentinfo">
    <div id="KerryCodeSignature">
<div>
<img src="https://images.cnblogs.com/cnblogs_com/kerrycode/1913302/o_240731062102_kerrycode.png" height="120" width="500">
</div>
<div>
<b>扫描上面二维码关注我</b>
</div>
<div>如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!</div>
<div>本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.</div>
</div><br><br>
来源:https://www.cnblogs.com/kerrycode/p/19087903
頁: [1]
查看完整版本: MySQL如何统计/监控MySQL用户登录失败?