MySQL设置管理员密码无法生效的案例一则
Posted bisal(Chen Liu)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL设置管理员密码无法生效的案例一则相关的知识,希望对你有一定的参考价值。
爱可生开源社区的这篇文章《技术分享 | MySQL 设置管理员密码无法生效一例》介绍了管理员账号密码不能生效的一则场景案例,一方面可以了解都有什么原因可能导致出现这种场景,另一方面就是对这种问题的排查路径,还是非常值得借鉴的,学习一下。
昨天某位客户咨询这样一个问题:他通过本地mysql命令行连接数据库发现管理员不需要验证密码即可进行后续操作。为了查明原因,他尝试过修改管理员密码,依然无效。为了对比,他还特意创建了一个带密码的新用户,通过MySQL命令行可以正常进行密码验证。
此类问题大致会有如下几种原因:
此用户本身并没有设置密码。
配置文件里开启skip-grant-tables跳过授权表。
配置文件里有明文password选项来跳过密码。
用户的认证插件有可能使用auth_socket。
先来大致复现下这个问题。
现象如下:MySQL命令行客户端打印“hello world”不需要验证密码,
root@ytt-large:/home/ytt# mysql -e "select 'hello world'"
+-------------+
| hello world |
+-------------+
| hello world |
+-------------+
换个用户就验证密码后方可正常打印字符串,
root@ytt-large:/home/ytt# mysql -uadmin -e "select 'hello world'"
ERROR 1045 (28000): Access denied for user 'admin'@'localhost' (using password: NO)
root@ytt-large:/home/ytt# mysql -uadmin -p -e "select 'hello world'"
Enter password:
+-------------+
| hello world |
+-------------+
| hello world |
+-------------+
尝试修改管理员密码,依然不需要验证密码即可执行命令:看结果好像是修改密码无效,
root@ytt-large:~# mysql
Welcome to the MySQL monitor. Commands end with ; or \\g.
Your MySQL connection id is 35
Server version: 8.0.29 MySQL Community Server - GPL
...
mysql> alter user root@localhost identified by 'root';
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
root@ytt-large:/home/ytt# mysql -e "select 'hello world'"
+-------------+
| hello world |
+-------------+
| hello world |
+-------------+
接下来基于复现的场景以及开头想到的可能原因来逐步判断到底问题出在哪里。
1. 此用户本身并没有设置密码
这个原因可以快速排除掉。因为已经执行过一次alter user改密码的操作,所以不可能没有密码。
2. 配置文件里开启skip-grant-tables跳过授权表
这个原因也可以快速排除掉。如果是因为开启这个选项,那必定所有用户都不会验证密码,而不只是针对管理员账号本身。
3. 配置文件里有明文password选项来跳过密码
有可能是这个原因。可以用工具my_print_defaults来打印相关配置、或者直接手动检查配置文件有没有[client]、[mysql]等段里包含有password明文选项。例如,
root@ytt-large:/home/ytt# my_print_defaults /etc/mysql/my.cnf client mysql
--password=*****
结果确实是设置了password选项,但是仔细想想,有点站不住脚。如果是因为这个原因,那修改密码后,为什么依然不验证新密码?因此这个可能性也被排除掉。
4. 用户的认证插件有可能使用auth_socket
极有可能是这个原因。
插件auth_socket在MySQL官网全称为:Socket Peer-Credential Pluggable Authentication(套接字对等凭据可插拔的身份验证)。
官方文档地址:
https://dev.mysql.com/doc/refman/8.0/en/socket-pluggable-authentication.html
阅读官方文档后可以得出的结论为插件auth_socket不需要验证密码即可进行本地认证。他有两个认证条件,
客户端通过本地unix socket文件连接MySQL服务端。
2. 通过socket的选项SO_PEERCRED来获取运行客户端的OS用户名,随后判断OS用户名是否在mysql.user表里。
另外,想了解更多关于socket的选项SO_PEERCRED可以参考这个网址:
https://man7.org/linux/man-pages/man7/unix.7.html
我们接下来验证结论是否正确。查看当前登录用户是不是root@localhost,确认无疑,
root@ytt-large:/home/ytt# mysql -e "select user(),current_user()"
+----------------+----------------+
| user() | current_user() |
+----------------+----------------+
| root@localhost | root@localhost |
+----------------+----------------+
检查mysql.user表记录:检查字段plugin、authentication_string(此字段有可能不为空),
mysql> select plugin,authentication_string from mysql.user where user = 'root' ;
+-------------+-----------------------+
| plugin | authentication_string |
+-------------+-----------------------+
| auth_socket | |
+-------------+-----------------------+
1 row in set (0.01 sec)
确认管理员账号插件为auth_socket,难怪改密码无效。接下来把插件改为非auth_socket即可,
mysql> alter user root@localhost identified with mysql_native_password by 'root';
Query OK, 0 rows affected (0.04 sec)
再次执行MySQL命令行:无密码正常报错,输入正确密码后执行成功,
root@ytt-large:/home/ytt# mysql -p -e "select 'hello world'"
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@ytt-large:/home/ytt# mysql -proot -e "select 'hello world'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| hello world |
+-------------+
| hello world |
+-------------+
因此,一般在遇到MySQL问题时,建议对MySQL系统函数、数据库内部对象等进行检索而不是直接打印字符串,有时候可能对快速定位问题原因有帮助。
MySQL一直给我的感觉就是很多功能和参数关系紧密,出问题的时候,很多场景都会和参数相关,参数越多,从控制的粒度,以及个性化的配置角度,就会更加方便,但同时就给MySQL精细化地使用提出了更高的要求。不同的数据库,由于站的角度可能不同,设计实现层面,还是有很多不一样的理解。
近期更新的文章:
文章分类和索引:
以上是关于MySQL设置管理员密码无法生效的案例一则的主要内容,如果未能解决你的问题,请参考以下文章