从两条不同路径输入同一个用户名,MariaDB 可能把你认证成两个不同的账户。账户由用户名与主机共同确定,因此 'reporter'@'localhost' 与 'reporter'@'10.90.0.23' 是两行独立的记录,密码不同、授权也不同。走 VPN 时,真正值得问的不是用户输入了什么名字,而是服务器看到的源地址。

确定服务器实际看到的来源

要从数据库主机往回查,而不是从笔记本往前猜。客户端自认为拥有的地址只是几种可能之一:

PathSource MariaDB sees
Routed tunnel, no translationThe client's inner VPN address
Gateway source translationThe gateway's translated address
SSH local forwardThe SSH server's address
Public exit, no tunnelWhatever the ISP handed out

用服务器侧的证据来判定。连接日志、活动会话列表或临时开启的通用日志会显示服务器接受的地址。浏览器里看到的笔记本公网 IP 是另一回事,而且经常误导人。

对上 MariaDB 实际选中的账户

账户选择遵循有文档规定的顺序,而不是把授权做并集。精确的主机匹配优先于通配符,匿名用户行也会以出人意料的方式参与匹配,认为只看名字就能决定的人往往会判断错。服务器只选一行,不会把同名各行的权限合并。读一遍参考文档,比花一下午试错更值。

也就是说,如果会话是以 'reporter'@'10.90.0.23' 认证的,往 'reporter'@'%' 上加授权可能什么都不会变。修复必须落在被选中的那一行上,所以先确认账户,再改授权。

读取会话实际使用的账户

SELECT USER(), CURRENT_USER();
SHOW GRANTS;

CURRENT_USER() 给出的是通过认证的账户;USER() 报告的是客户端请求的身份,两者可能不一致。这些要作为普通的最上层查询执行,而不是在带 definer 上下文的存储程序里执行,否则答案描述的是程序所有者,而不是你的会话。

登录失败时这些查询一条都跑不了,这正是管理员必须转而检查账户定义和服务器连接证据的情形。要提前想到这一点:排查被拒登录的人,通常根本没有可用的 SQL 会话。

把可达性与认证分开

报错文本会告诉你卡在哪一层。连接被拒或超时,说明客户端根本没到达监听端口,账户和密码还轮不到讨论。返回拒绝访问,说明服务器确实回应了,这证明网络可达,问题指向账户、主机匹配或凭据。

网络前提本身就是一份清单:监听要绑在预期地址上而不只是回环地址,配置端口要放行,回程路由要存在。每一项都可能独立失败,隧道通了并不代表其中任何一项成立。只绑回环的监听会接受本地连接、拒绝所有远程连接,表现出的连接被拒很像防火墙拦截。

在给网络团队开单之前,先确认绑定地址。数据库主机上的 ss -lntp 会显示究竟是哪个地址和端口在监听,这一行就能排除一整类猜测。

收窄修复范围,然后双向复测

通过组织认可的流程创建预期的、带主机限定的账户,凭据取自受支持的存储,而不是贴进工单里的共享口令。只授予任务所需的库表操作。把失败的远程登录改成 root 账户、全放开策略或大范围通配主机,能让测试通过,却拿掉了你本来要验证的那道控制。匆忙加上的授权,往往就是后来没人回收的那条。

用新会话沿预期路径复测,然后检查反向用例。本该被挡住的路径必须仍然被挡住,没有授予的操作必须仍然被拒绝。这两项检查,才是修好了和放开了的分界。

最后,把观察到的源地址和账户名一起记录下来。隧道只提供可达性;MariaDB 仍然自己选择和授权账户,下一个人需要这两项事实才能复现你的结果。

相关文章