问题背景

用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 指代 主机)

  1. Host 表示 允许账户从哪台主机访问数据库。主要用于做安全限制,可以是 主机名、IP地址、%(通配符);
  2. User 允许重复,只要 Host 是不同的就行。
  3. 当 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表 中存在多条匹配记录,该以哪条记录为准?

答案是“优先级”。大致规则如下:

  1. 首先,检查 Host 字段。如果有多个 Host 符合条件,则选择匹配度最高的记录(IP地址 > 通配符%)。
  2. 其次,检查 User 字段。如果有多个 User 符合条件,则选择匹配度最高的记录。匿名用户可以匹配任何用户,因此匹配度最低。

优先级匹配例子

举例,假设本地数据库有如下两个账户(Password字段实际非明文)。

+------------+-----------+-----------+
| User | Host | Password |
+------------+-----------+-----------+
| my_account | % | 123 |
| | localhost | 456 |
+------------+-----------+-----------+

运行如下命令,最终登录的账户,匹配的是 第2条 记录。(读者可自行尝试,输入密码123登录失败,输入456登录成功)

mysql -u my_account -p

为什么呢?回顾下匹配的优先级。

  1. 首先,检查 Host 字段。localhost、% 都符合要求。localhost 匹配度高于 %,因此匹配到第2条记录。
  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数据库拒绝访问的解决过程的更多相关文章

  1. SQL Server附加数据库拒绝访问错误解决方法

    今天在MsSQL里附加数据库时提示操作系统错误5(拒绝访问),这里我没给出了两个解决方案供大家解决问题. 方案一:切换登录方式 出现这种情况是由于用“混合验证方式”(SQL Server身份验证)登录 ...

  2. 把本地windows系统上的mysql数据库移到linux系统服务器上,mysql数据库拒绝访问

    Mysql连接报错 原因是:远程服务器不允许你的其他程序访问它的数据库.所以,我们要对远程服务器进行设置,使它允许你进行连接. 步骤:一.进入mysql客户端,输入:use mysql; 二.输入:s ...

  3. SonarQube 启动无报错但是拒绝访问的解决过程及方案

    启动sonarqube [sonar_user@Sonnarqube-dev linux-x86-64]$ ./sonar.sh start 查看网页: 排错步骤 第一步输入启动过程命令查看启动信息 ...

  4. 记一次mysql数据库被勒索(中)

    背景在上一篇文章里面已经提过了. 现在面临的问题是nextcloud没有mysql数据库,用不起来了. 因为文件没丢,一种方法是启动新的mysql数据库,把文件重新提交一次. 为了程序员的面子,没有选 ...

  5. 记一次mysql数据库被勒索(下)

    背景: nextcloud的mysql数据库被黑,删库勒索.参考:记一次mysql数据库被勒索(上) mysql数据库恢复成功,nextcloud还是无法连接.参考:记一次mysql数据库被勒索(中) ...

  6. MySQL数据库忘记root密码解决办法

    MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图:

  7. asp.net 未能写入输出文件--“拒绝访问”的解决办法

      概述 将网部署在IIS 7 上,访问本地磁盘路径的时候,提示"**文件拒绝访问".   解决办法   将需要访问的文件夹赋于IIS_IUSRS完全控制的权限即可,不用添加NET ...

  8. [原创]MySQL数据库忘记root密码解决办法

    MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图:

  9. [异常篇]001.MySQL数据库忘记root密码解决办法[转载]

    MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图: 2.在运行输入cmd打开终端. 3.找到MYSQL的安装目录 ...

随机推荐

  1. Oracle删除重复行

    Oracle删除重复行 分类: ORACLE2010-12-12 17:10 423人阅读 评论(0) 收藏 举报 oracletabledeleteintegerinsert.net 查询及删除重复 ...

  2. Git分支创建与合并

    分支管理是Git支持多人协作和版本控制的关键,参照廖雪峰对Git的介绍,对真实开发环境中Git的使用结合实践进行梳理. 摘自:廖雪峰的官方网站 在实际开发中,我们应该按照几个基本原则进行分支管理: 首 ...

  3. PHP实现单例模式和观察者模式

    单例模式的实现: PHP中单例模式常用在数据库连接部分,省掉了大量的new操作进而节省了很多资源.单例模式还可以用在全局配置类中. 单例模式,顾名思义就是说只有一个实例,这就要求防止外部随意实例化对象 ...

  4. HTML 学习笔记 day one

    HTML学习笔记 day one Chapter one 网站开发基础 1.2网站的基本架构 网站的基本要素:内容,页面,超链接 动态网页和静态网页的区别在于:动态网页会自动更新,后缀名是.asp或者 ...

  5. SOFA 源码分析 — 预热权重

    前言 SOFA-RPC 支持根据权重对服务进行预热功能,具体地址:预热权重. 引用官方文档: 预热权重功能让客户端机器能够根据服务端的相应权重进行流量的分发.该功能也常被用于集群内少数机器的启动场景. ...

  6. 原生Feign使用详解

    一,简介 Feign使得 Java HTTP 客户端编写更方便.Feign 灵感来源于Retrofit.JAXRS-2.0和WebSocket.Feign最初是为了降低统一绑定Denominator到 ...

  7. Linux(二十一)Shell编程

    21.1 为什么要学习Shell编程 (1)Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理. (2)对于JavaEE和Python程序员来说,工作的需要,你的老大会 ...

  8. Mysql主从方案的实现

    Mysql主从方案介绍 mysql主从方案主要作用: 读写分离,使数据库能支撑更大的并发.在报表中尤其重要.由于部分报表sql语句非常的慢,导致锁表,影响前台服务.如果前台使用master,报表使用s ...

  9. selenium+python自动化测试

    F12: 右键   选择复制  path 在selenium+python自动化测试(一)–环境搭建中,运行了一个测试脚本,脚本内容如下: from selenium import webdriver ...

  10. 二十五、Hadoop学记笔记————Hive复习与深入

    Hive主要为了简化MapReduce流程,使非编程人员也能进行数据的梳理,即直接使用sql语句代替MapReduce程序 Hive建表的时候元数据(表明,字段信息等)存于关系型数据库中,数据存于HD ...