暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

MySQL 未经身份验证的用户(unauthenticated user)解读

原创 CuiHulong 2024-12-31
744

在使用MySQL当中,偶尔会碰到,执行SHOW PROCESSLIST的发现有很多未经身份验证的用户。链接信息都有了,如下:

mysql > SHOW PROCESSLIST +--+----------------------+--------------------+------+---------+------+----- -+------------------+ |Id| User | Host | db | Command | Time | State| Info +--+----------------------+--------------------+------+---------+------+----- -+------------------+ | 1| unauthenticated user | connecting host | NULL | Connect | 39173 | login| NULL|0 | 0 | | 2| unauthenticated user | connecting host | NULL | Connect | 39098 | login| NULL|0 | 0 | | 3| unauthenticated user | connecting host | NULL | Connect | 39037 | login| NULL|0 | 0 | | 4| unauthenticated user | connecting host | NULL | Connect | 38941 | login| NULL|0 | 0 | | 5| unauthenticated user | connecting host | NULL | Connect | 38885 | login| NULL|0 | 0 | 。。。

为什么会出现这样的情况,先看看官方解说:
When a user connects to MySQL but has not yet sent their credentials, MySQL does not know the actual user’s name yet. Until the user sends its login credentials, MySQL returns “unauthenticated user” in the running process’s user column. Once the user is authenticated and sends commands, you should see the correct username
当用户连接到MySQL但尚未发送凭据时(没有进行密码验证),MySQL还不知道实际用户名。就是说用户发送其登录凭据之前,MySQL在运行进程的用户列中返回“unauthenticated user”未经身份验证的用户。一旦用户通过身份验证并发送命令,就能看到正确的用户信息。

真的是这样吗!通过多方面分析,如下场景会出现上述情况:

  • 如果由于应用安全问题出现大量MySQL数据库探测,有可能会出现大量这种未经授权的连接。
  • 应用服务压力过大出现线程异常中断导致出现大量异常MySQL数据库连接。
  • 应用服务到MySQL服务器的网络异常,客户端由于某些参数配置不正确致使正常的请求没有在规定时间内发出,MySQL无法验证连接的有效性。
  • MySQL客户端连接版本问题,验证协议不兼容,尤其注意早起old-password验证方式。
  • MySQL服务的线程处于排队状态。

下面通过Telnet模拟下未经授权的场景:
image.png
因为Telnet只是单存访问服务端口是否存在。无认证信息。所以显示成unauthenticated user。

分析过程

1.DNS问题

MySQL服务默认维护一个内存中的主机缓存,其中包含有关客户端的信息:IP地址、主机名,计数信息。主机缓存信息,能让之前连接过的应用快速的建立连接通道。但有时,因在客户端访问MySQL服务时,因为需要匹配DNS信息,无法正确解析DNS信息导致SHOW PROCESSLIST时显示 “unauthenticated user”。即:先作反向解析IP>Hostname,然后作Hostname>IP的正向解析。如果结果符合,则验证为合法用户允许登录,如果不符合则定义为“unauthenticated user”。

所以按照MySQL数据库维护中,经常会建议设置skip_name_resolve参数。关闭解析DNS解析。如需要开启DNS,那就需要关注主机缓存的相关指标。

2.超时参数优化

超时相关参数:
MySQL中基础的超时参数,如下所示:

MySQL > show variables like '%_timeout%'; +-------------------------------------------+----------+ | Variable_name | Value | +-------------------------------------------+----------+ | connect_timeout | 10 | | interactive_timeout | 28800 | | wait_timeout | 28800 | +-------------------------------------------+----------+ 26 rows in set (0.00 sec)

说明如下:

  • connect_timeout:MySQL服务在以错误握手响应之前等待连接数据包的秒数。默认值为10秒。
  • wait_timeout:MySQL服务在关闭非交互式连接之前等待其活动的秒数。
  • interactive_timeout:MySQL服务在关闭交互式连接之前等待其活动的秒数。

其中交互式和非交互式都是链接成功之后,无活动才进入的状态,所以账号信息肯定会记录下来。最有可能是connect_timeout参数,因为要等待认证的数据包,在等待当中,如果网络堵塞,数据包被注入木马之类的,就有可能会导致认证失败。
可以调整connect_timeout 链接握手时间减小。

3.back_log参数优化

MySQL可以具有的未完成连接请求的数量。当MySQL主线程在很短的时间内收到很多连接请求时(连接数达到max_connections),新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。
back_log值不能超过TCP/IP连接的侦听队列的大小。

shell# cat /proc/sys/net/ipv4/tcp_max_syn_backlog

#修改系统内核参数,编辑/etc/sysctl.conf进行调整,之后执行sysctl -p 立即生效。
shell# vim /etc/sysctl.conf
net.ipv4.tcp_max_syn_backlog = 2048

4.服务影响

当unauthenticated user没有完成整个认证过程,但其实已经占据一个连接数。当这种用户多的情况下,会导致连接数爆满。可通过MySQL STATUS指标查看:
image.png

5.解决方案

对于unauthenticated user,给与下面几种解决方案:
1.调整connect_timeout链接握手时间减小(比如:3s), 快速释放异常链接。
2.禁用DNS反向解析。如需要开启DNS解析,最好手动配置hosts文件。(可以在/etc/hosts添加对应IP信息)
3.增加侦听队列(back_log,tcp_max_syn_backlog)增加MySQL处理连接请求的能力。

总结

在MySQL中大量的未认证用户进程(unauthenticated user),会影响数据库的性能和稳定性。可以结合netstat,ping,tcpdump等命令行尽快排查源头,解决异常。

欢迎加入MySQL社区交流群【MySQL 从1开始交流群】
image.png

最后修改时间:2025-01-02 12:13:45
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论