当前位置: 首页 > news >正文

技术分享 | MySQL 设置管理员密码无法生效一例

 作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

本文来源:原创投稿

* 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


昨天某位客户向我咨询这样一个问题:他通过本地 MySQL 命令行连接数据库发现管理员不需要验证密码即可进行后续操作。为了查明原因,他尝试过修改管理员密码,依然无效。为了对比,他还特意创建了一个带密码的新用户,通过 MySQL 命令行可以正常进行密码验证。

经过对他遇到的问题做了详细了解后,我大概知道问题出在哪,不过还需要继续验证。

此类问题大致会有如下几种原因:
  1. 此用户本身并没有设置密码。

  2. 配置文件里开启 skip-grant-tables 跳过授权表。

  3. 配置文件里有明文 password 选项来跳过密码。

  4. 用户的认证插件有可能使用 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 改密码的操作,所以不可能没有密码。

  1. 配置文件里开启 skip-grant-tables 跳过授权表。

这个原因也可以快速排除掉!如果是因为开启这个选项,那必定所有用户都不会验证密码,而不只是针对管理员账号本身。

  1. 配置文件里有明文 password 选项来跳过密码。

有可能是这个原因。可以用工具 my_print_defaults 来打印相关配置、或者直接手动检查配置文件有没有[client] 、[mysql] 等段里包含有 password 明文选项。例如:

root@ytt-large:/home/ytt# my_print_defaults /etc/mysql/my.cnf client mysql
--password=*****

结果确实是设置了 password 选项,但是仔细想想,有点站不住脚。如果是因为这个原因,那修改密码后,为什么依然不验证新密码?因此这个可能性也被排除掉。

  1. 用户的认证插件有可能使用 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 不需要验证密码即可进行本地认证!它有两个认证条件:

  1. 客户端通过本地 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 日常问题#

相关文章:

  • 7个人生工具:SWOT、PDCA、6W2H、SMART、WBS、时间管理、二八原则
  • GoldenGate案例一则:抽取进程无法捕获数据
  • 最近的一些杂感-20220613
  • 针对 MySQL/InnoDB 刷盘调优
  • 技术分享 | MySQL 编写脚本时避免烦人的警告
  • 十多年前的入职第一天
  • 招贤纳士-第23期
  • 技术分享 | MySQL:caching_sha2_password 快速问答
  • MySQL8.0账户system_user权限,你了解吗?
  • 互动送书-《Oracle DBA工作笔记》签名版
  • 招贤纳士-第24期
  • 新特性解读 | MySQL 8.0 对 GTID 的限制解除
  • MySQL:不是MySQL问题的MySQL问题
  • MySQL 8.0.30 GA
  • 最近的一些杂感-20220731
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • CSS相对定位
  • ESLint简单操作
  • Idea+maven+scala构建包并在spark on yarn 运行
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Selenium实战教程系列(二)---元素定位
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 解析 Webpack中import、require、按需加载的执行过程
  • 类orAPI - 收藏集 - 掘金
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 异步
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ###C语言程序设计-----C语言学习(3)#
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (02)Hive SQL编译成MapReduce任务的过程
  • (2)MFC+openGL单文档框架glFrame
  • (3)选择元素——(17)练习(Exercises)
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转) Android中ViewStub组件使用
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • (转载)(官方)UE4--图像编程----着色器开发
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .net mvc部分视图
  • .NET 反射 Reflect
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .NET值类型变量“活”在哪?
  • :not(:first-child)和:not(:last-child)的用法
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [C++进阶篇]STL中vector的使用
  • [CISCN 2019华东南]Web11
  • [COI2007] Sabor