记一次MySQL数据库拒绝访问的解决过程

解决MySQL匿名账户导致的本地连接问题
本文探讨了使用WordPress和MySQL时遇到的数据库连接拒绝问题,详细解析了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 指代 主机)

  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

原文首发在笔者的个人博客,地址在这里

转载于:https://www.cnblogs.com/chyingp/p/mysql-access-denied-because-of-anonymous-user.html

### Windows 环境下 MySQL 数据库访问拒绝问题的解决方案 在 Windows 系统中,当通过 Node.js 或其他工具连接 MySQL 数据库时,如果出现 `Access denied for user 'root'@'localhost' (using password: YES)` 错误,通常是由于以下几个原因之一引起的:用户名或密码错误、权限不足、或者主机名配置不正确。以下是详细的分析与解决方法。 --- #### **1. 用户名或密码错误** - 如果输入的用户名或密码不正确,MySQL 会返回该错误消息。 - 可以尝试重新验证登录凭证是否正确。例如,在命令行中运行以下语句来测试连接: ```bash mysql -u root -p ``` 随后输入对应的密码。如果无法成功登录,则说明用户名或密码存在问题[^1]。 --- #### **2. 权限不足** 即使提供了正确的用户名和密码,如果没有足够的权限访问特定数据库,仍会出现拒绝访问的问题。 ##### 授予权限给指定用户 可以通过执行以下 SQL 查询授予权限给某个用户(假设为 `'root'@'localhost'`): ```sql GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY '123456'; FLUSH PRIVILEGES; ``` 这里需要注意两点: - 替换 `test` 为目标数据库名称; - 使用实际的密码替换 `'123456'`[^2]。 --- #### **3. 主机名配置问题** 某些情况下,默认允许本地连接 (`localhost`) 的用户可能未被授权从远程地址或其他 IP 地址进行连接。因此需要显式定义支持任意主机名 `%` 的用户录。 ##### 创建全局可访问用户 可以新增一条规则使得 `'root'@'%'` 能够无限制地访问整个实例下的资源: ```sql CREATE USER 'root'@'%' IDENTIFIED BY 'your_password_here'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; FLUSH PRIVILEGES; ``` 这样做的目的是让来自网络上的客户端也能正常请求服务端的数据接口[^3]。 --- #### **4. 特殊情况处理** 有时候即便完成了以上步骤依旧存在障碍,那么还需要考虑额外的因素比如防火墙阻挡外部流量进入服务器内部监听端口;或者是安装过程中选择了较为严格的初始化参数从而禁用了匿名登陆等功能特性等等。 ##### 检查防火墙设置 确保 Windows 防火墙没有阻止 MySQL 默认端口号 3306 的入站规则。可以在 PowerShell 中添加例外规则如下所示: ```powershell New-NetFirewallRule -DisplayName "Allow MySQL" -Direction Inbound -LocalPort 3306 -Protocol TCP -Action Allow ``` --- ### 总结 通过对上述几个方面的逐一排查,基本可以定位并解决大部分关于 Windows 平台下 MySQL 数据库访问遭拒的情况。重要的是始终保持良好的安全管理习惯,定期审查账户列表以及它们各自拥有的权利范围,防止不必要的安全隐患引入系统之中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值