DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

MariaDB 本机 root 报 Access denied,sudo 却能登录:检查 unix_socket

本机 MariaDB root 密码登录失败而 sudo 登录成功时,查看完整认证定义;保留管理入口,给应用建立限定权限账号,并区分 socket 与 TCP。

Linux 上安装 MariaDB 后,普通用户执行 mariadb -u root -p 报 Access denied for user 'root'@'localhost',但 sudo mariadb 能登录,往往需要检查 unix_socket 认证。这个插件使用本机 Unix socket 连接的操作系统身份,输入数据库密码并不能让普通系统用户变成系统 root。

这种配置常见于 Debian/Ubuntu 的 MariaDB 软件包。MariaDB 10.4 起还支持一个账号使用多种认证方式,默认初始化的 root@localhost 可以包含 unix_socket 与密码认证分支。实际安装方式、初始化参数和后续账号修改都可能改变配置,所以先看账号定义,不应仅凭版本推断。

先确认用的是 socket 连接

有本机管理权限的人,可以显式指定 socket 登录。以下命令是读者操作示例,会进入数据库管理会话,并没有修改账号:

sudo mariadb --protocol=socket -u root

显式的 --protocol=socket 避免系统客户端配置中 protocol=tcp 改变连接方式。如果实例使用非默认 socket,还需要按实际部署指定 --socket 路径。不要把数据库主机的管理员登录方式当作远程应用连接方式。

若依旧报错,先确认目标实例、socket 路径和是否仍保留 unix_socket。sudo 登录只对配置允许的本地身份认证有效,并不是万能密码恢复办法。

登录后执行只读检查:

SELECT VERSION(), USER(), CURRENT_USER();
SHOW CREATE USER 'root'@'localhost';
SHOW GRANTS FOR 'root'@'localhost';

USER() 表示客户端连接身份,CURRENT_USER() 表示实际匹配的数据库账号。SHOW CREATE USER 用于查看完整认证规则,输出可能包含密码散列等敏感信息,只保存到受保护的管理记录,不公开粘贴。

从完整定义判断,不直接更新 mysql.user

若账号定义包含 IDENTIFIED VIA unix_socket,应从有权限的系统身份通过本地 socket 管理。普通系统用户即使指定 -u root,也不符合该认证条件。

MariaDB 10.4 起的默认初始化可能出现如下认证部分,以下仅为示例片段:

IDENTIFIED VIA unix_socket OR mysql_native_password USING 'invalid'

这里的 invalid 不是可输入的登录密码,而是尚不能通过密码认证的初始值。账号是否已设置可用密码,仍需检查实际定义和管理记录。

MariaDB 10.4 起 mysql.user 是基于 mysql.global_priv 的视图,单看 plugin 列也无法完整表达所有备用认证方式。旧式 UPDATE mysql.user SET plugin=... 可能报列不可更新,更不应把针对全部 unix_socket 用户的更新语句用于生产。

直接替换 root 的认证方式还可能影响依靠本地 socket 的升级、备份或维护脚本。只是让应用能够连接时,没有必要先修改这个管理账号。

给应用创建限定权限的密码账号

如果目标是让本机应用、图形客户端或服务使用密码连接,保留 root 的管理路径,为应用创建单独账号。下例针对通过同一台 Linux 主机的 Unix socket 访问已经存在的 appdb,数据库名、用户名和密码都是占位值:

CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'REPLACE_WITH_GENERATED_SECRET';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app_user'@'localhost';

这会新增账号并授予 appdb 的基本读写权限,不包含建表、删表或管理权限。只读程序应进一步缩小权限;迁移程序需要的 DDL 权限另行评估。密码应由可信管理渠道生成和保存,SQL 输入记录也需按凭据保护。

MariaDB 在 Linux 上的 'localhost' 账号匹配 Unix socket,不能将它与 TCP 的 127.0.0.1 混为一谈。应用若通过 TCP、另一台机器或容器访问,应根据服务器实际看到的来源地址建立相应账号,并使用环境要求的 TLS。不能把 'localhost' 简单改成 '%',同时授予全局权限,以此处理所有连接问题。

以上新增账号和授权正常情况下不需要重启服务器,也不需要额外执行 FLUSH PRIVILEGES。若配置不合适,先把应用恢复到原连接设置,再撤销这个新账号的授权或删除它;删除前确认没有其他程序使用,并保存账号定义与授权记录。

分别确认管理入口与应用连接

应用账号应通过与应用相同的传输方式验证。对上面的本地 socket 示例,可使用:

mariadb --protocol=socket -u app_user -p appdb

进入后检查 CURRENT_USER()、DATABASE() 和 SHOW GRANTS。应匹配 app_user@localhost,默认库为 appdb,权限只覆盖既定用途。

同时确认本机管理员原有的 socket 登录仍然有效,备份或维护程序没有因账号变更而失败。若应用错误是 Host ... is not allowed、socket 文件找不到或连接拒绝,需要分别处理账号来源匹配、路径和监听问题,不能只靠重设 root 密码解决。