记一次MySQL数据库拒绝访问的解决过程
问题背景
用wordpress搭博客,数据库采用MySQL。为了调试方便,创建账户my_account ,允许它从任意主机访问数据库。
CREATE USER `my_account`@'%' IDENTIFIED BY 'my_password';
修改 wp-config.php 相应配置,注意 DB_HOST 设置为 127.0.0.1。
define('DB_USER', 'my_account'); // 账号
define('DB_PASSWORD', 'my_password'); // 密码
define('DB_HOST', '127.0.0.1'); // 数据服务地址
部署到云服务器上,本地浏览器访问博客,提示数据库拒绝访问(本地连接远程数据没问题),以下为错误日志。
ERROR 1045 (28000): Access denied for user 'my_account'@'localhost' (using password: YES)`
简单排查后,解决了问题,这里记录下解决方案,以及出错的原因。
解决方案
1、方案一:删除 mysql.user表 中,Host字段为 localhost 的匿名账号(账户名为空)。
2、方案二:创建 my_account@localhost 账户,用于本地连接数据库。
笔者采用了方案 一。
首先,确认下 mysql.user 表中是否存在匿名账户。
MariaDB [(none)]> SELECT User, Host from mysql.user WHERE Host = 'localhost' AND User = '';
+------+-----------+
| User | Host |
+------+-----------+
| | localhost |
+------+-----------+
1 row in set (0.00 sec)
接着,删除相应匿名账户,再次尝试登陆,成功。
MariaDB [(none)]> DROP USER ''@'localhost';
Query OK, 0 rows affected (0.00 sec)
问题分析
为什么匿名账户会导致数据库连接失败?
需要对MySQL的账户创建、客户端连接校验有一定的了解。
创建MySQL账户
基础语法如下:
CREATE USER 账户名@主机 IDENTIFIED BY 密码;
注意点:(以下用 User 指代账户名,Host 指代 主机)
- Host 表示 允许账户从哪台主机访问数据库。主要用于做安全限制,可以是 主机名、IP地址、%(通配符);
- User 允许重复,只要 Host 是不同的就行。
- 当 Host 设置为 % 时,表示允许从任意主机连接数据库。
比如,存在两个xiaoming账户,一个允许从本机连接数据库,一个允许从 14.215.177.39 连接数据库。
MariaDB [(none)]> SELECT User, Host FROM mysql.user WHERE User = 'xiaoming';
+---------+---------------+
| User | Host |
+---------+---------------+
| xiaoming | 14.215.177.39 |
| xiaoming | localhost |
+---------+---------------+
2 rows in set (0.00 sec)
匿名账户
也就是 User 为空的账户,可以匹配任意用户名。如下指令创建了匿名账户。
CREATE USER ''@'localhost' IDENTIFIED BY 'pwd3';
身份校验
数据库服务器收到客户端连接,首先会进行身份校验,将 User、Host、Password 字段,跟 mysql.user 表里的记录进行比较,确认是否合法账户。
这里有个问题:如果 mysql.user表 中存在多条匹配记录,该以哪条记录为准?
答案是“优先级”。大致规则如下:
- 首先,检查 Host 字段。如果有多个 Host 符合条件,则选择匹配度最高的记录(IP地址 > 通配符%)。
- 其次,检查 User 字段。如果有多个 User 符合条件,则选择匹配度最高的记录。匿名用户可以匹配任何用户,因此匹配度最低。
优先级匹配例子
举例,假设本地数据库有如下两个账户(Password字段实际非明文)。
+------------+-----------+-----------+
| User | Host | Password |
+------------+-----------+-----------+
| my_account | % | 123 |
| | localhost | 456 |
+------------+-----------+-----------+
运行如下命令,最终登录的账户,匹配的是 第2条 记录。(读者可自行尝试,输入密码123登录失败,输入456登录成功)
mysql -u my_account -p
为什么呢?回顾下匹配的优先级。
- 首先,检查 Host 字段。localhost、% 都符合要求。localhost 匹配度高于 %,因此匹配到第2条记录。
- 接着,检查 User 字段。第2条记录是匿名账户,可匹配任意User值,因此,第2条记录符合要求。
因此,虽然账户 my_account 的 Host字段 为%,但是在本地(数据库所在主机)连接数据库时,因为上述规则的存在,MySQL 会认为你是用匿名账户在登录。
my_account 跟匿名账户的密码是不同的,因此密码校验不通过,拒绝访问。
写在后面
因匿名用户存在,导致本地连接数据库拒绝连接,这个问题很常见,有不少人认为这是MySQL的设计缺陷,比如 这里。
了解了MySQL的身份验证逻辑,遇到类似问题也就有思路了。关于%通配符,匹配优先级,上文并没有详细展开,感兴趣的读者可以自行查看官方文档。
另外,MySQL拒绝访问的原因有多种,读者应具体问题具体分析。
如有错漏,敬请指出。
相关链接
Host wildcard % which is said in docs that means "all hosts" excludes localhost
6.2.4 Access Control, Stage 1: Connection Verification
记一次MySQL数据库拒绝访问的解决过程的更多相关文章
- SQL Server附加数据库拒绝访问错误解决方法
今天在MsSQL里附加数据库时提示操作系统错误5(拒绝访问),这里我没给出了两个解决方案供大家解决问题. 方案一:切换登录方式 出现这种情况是由于用“混合验证方式”(SQL Server身份验证)登录 ...
- 把本地windows系统上的mysql数据库移到linux系统服务器上,mysql数据库拒绝访问
Mysql连接报错 原因是:远程服务器不允许你的其他程序访问它的数据库.所以,我们要对远程服务器进行设置,使它允许你进行连接. 步骤:一.进入mysql客户端,输入:use mysql; 二.输入:s ...
- SonarQube 启动无报错但是拒绝访问的解决过程及方案
启动sonarqube [sonar_user@Sonnarqube-dev linux-x86-64]$ ./sonar.sh start 查看网页: 排错步骤 第一步输入启动过程命令查看启动信息 ...
- 记一次mysql数据库被勒索(中)
背景在上一篇文章里面已经提过了. 现在面临的问题是nextcloud没有mysql数据库,用不起来了. 因为文件没丢,一种方法是启动新的mysql数据库,把文件重新提交一次. 为了程序员的面子,没有选 ...
- 记一次mysql数据库被勒索(下)
背景: nextcloud的mysql数据库被黑,删库勒索.参考:记一次mysql数据库被勒索(上) mysql数据库恢复成功,nextcloud还是无法连接.参考:记一次mysql数据库被勒索(中) ...
- MySQL数据库忘记root密码解决办法
MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图:
- asp.net 未能写入输出文件--“拒绝访问”的解决办法
概述 将网部署在IIS 7 上,访问本地磁盘路径的时候,提示"**文件拒绝访问". 解决办法 将需要访问的文件夹赋于IIS_IUSRS完全控制的权限即可,不用添加NET ...
- [原创]MySQL数据库忘记root密码解决办法
MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图:
- [异常篇]001.MySQL数据库忘记root密码解决办法[转载]
MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图: 2.在运行输入cmd打开终端. 3.找到MYSQL的安装目录 ...
随机推荐
- 6.4 Schema 设计对系统的性能影响
前面两节中,我们已经分析了在一个数据库应用系统的软环境中应用系统的架构实现和系统中与数据库交互的SQL 语句对系统性能的影响.在这一节我们再分析一下系统的数据模型设计实现对系统的性能影响,更通俗一点就 ...
- AngularJs 学习笔记(四)服务
模型是指$scope上保存的包含瞬时状态数据的JavaScript对象. 服务是一个单例对象,只会被$injector实例化一次,并且是在需要的时候才会被创建,服务提供了把与特定功能相关联的方法集中在 ...
- springMVC 中的restful 架构风格
RESTful架构 : 是一种设计的风格,并不是标准,只是提供了一组设计原则和约束条件,也是目前比较流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. ...
- Android集成ffmpeg
1.ffmpeg官网文档地址:https://trac.ffmpeg.org/wiki/CompilationGuide/Android 2.上面页面资源列表里面第一项 https://github. ...
- SpringBoot19 集成SpringSecurity01 -> 环境搭建、SpringSecurity验证
1 环境搭建 1.1 创建一个SpringBoot项目 项目脚手架 -> 点击前往 1.2 创建一个Restful接口 新建一个Controller类即可 package com.example ...
- ThreadPoolExecutor 学习笔记
线程池的奥义 在开发程序的过程中,很多时候我们会遇到遇到批量执行任务的场景,当各个具体任务之间互相独立并不依赖其他任务的时候,我们会考虑使用并发的方式,将各个任务分散到不同的线程中进行执行来提高任务的 ...
- linux下错误的捕获:errno(errno.h)和strerror(string.h)的使用
参考:http://blog.csdn.net/starstar1992/article/details/52756387 linux下错误的捕获:errno和strerror的使用 经常在调用lin ...
- MySQL中横表和竖表相互转换
一 竖表转横表 1. 首先创建竖表 create table student ( id varchar(32) primary key, name varchar (50) not null, su ...
- 一个能够在Asp.Net和Asp.NetCore之间能够互相通讯的Rpc
一.特性 1.跨平台 2.提供负载均衡算法 3.支持ZK服务协调 4.提供了JSON.BinarySerializer.还有自定义的序列化方式 5.客户端提供Socket连接池,以便于快速交互,防止类 ...
- JVM-01:类的加载机制
本文从 纯洁的微笑的博客 转载 原地址:http://www.ityouknow.com/jvm.html 类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内 ...