访问服务器上的MySQL数据库,核心路径只有两条:通过SSH隧道加密连接,或直接开放3306端口并用客户端远程登录,前者更安全,后者更便捷,具体选哪种取决于你的使用场景和服务器环境。
远程连接MySQL前必须确认的三件事
很多人在第一步就卡住,不是命令敲错,而是基础条件没满足,先花两分钟确认以下三点,能省掉后面大量的排查时间。
- MySQL服务是否在运行:在服务器上执行
systemctl status mysqld或service mysql status,看到active(running)才算正常,如果没启动,执行systemctl start mysqld。 - 监听地址是否允许外部访问:默认安装的MySQL只监听127.0.0.1,这意味着只能本机访问,你需要检查配置文件
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf中的bind-address,把0.0.1改成0.0.0,然后重启服务。 - 防火墙和云安全组是否放行:这是初学者最容易忽略的环节,服务器本地的
firewalld或iptables,加上云厂商控制台里的安全组规则,两层都要放行对应端口,系统防火墙放行3306的命令是firewall-cmd --permanent --add-port=3306/tcp && firewall-cmd --reload,云安全组则在控制台添加入站规则,来源IP建议限定为你自己的公网IP,不要写0.0.0.0/0。
这三件事做完,你的MySQL才具备被远程访问的基本条件,接下来就是具体的连接方法。
通过SSH隧道访问MySQL的完整操作步骤
SSH隧道是最推荐的远程访问方式,尤其适合生产环境,它不需要额外开放3306端口,所有流量都走22号端口的加密通道,相当于给MySQL通信加了一层保护,业内专家普遍认为,只要是公网环境下的数据库访问,SSH隧道比裸奔的3306端口安全得多。
第一步:在本地建立SSH隧道
打开终端(Windows用户用PowerShell或CMD,macOS/Linux用户直接打开Terminal),执行以下命令:
ssh -N -L 3307:127.0.0.1:3306 用户名@服务器IP
这条命令的含义是:把本地电脑的3307端口,通过SSH隧道,转发到服务器上的127.0.0.1:3306,注意这里用的是3307而不是3306,是为了避免和本地可能已经安装的MySQL服务冲突。-N参数表示不执行远程命令,只做端口转发。
执行后输入服务器密码,隧道就在后台建立了,此时终端看起来像是卡住了,其实隧道已经在工作。
第二步:用本地客户端连接隧道端口
隧道建立后,你的本地电脑就有了一个”假”的MySQL端口3307,用任何MySQL客户端连接这个端口,就等于连接了服务器上的MySQL。
以命令行工具为例:
mysql -h 127.0.0.1 -P 3307 -u 用户名 -p
-h指向本地回环地址,-P指定端口3307,-u填你的数据库用户名,-p表示输入密码,回车后输入密码,就进入了MySQL命令行。
第三步:数据库账号授权是关键
很多用户在这一步栽跟头:SSH隧道通了,端口转发也正常,但连接时报Host 'xxx' is not allowed to connect to this MySQL server,原因很简单MySQL账号默认只允许localhost登录。
你需要先在服务器上执行授权命令:
GRANT ALL PRIVILEGES ON 你的数据库名. TO '用户名'@'localhost' IDENTIFIED BY '密码'; FLUSH PRIVILEGES;
注意,通过SSH隧道连接时,MySQL看到的来源地址依然是localhost,所以授权给localhost就足够了,如果你有多个数据库需要管理,可以授权给所有库:
GRANT ALL PRIVILEGES ON . TO '用户名'@'localhost' IDENTIFIED BY '密码';
这样配置后,SSH隧道方式就能稳定使用了。
怎么直接访问服务器上的mysql数据库而不走SSH
如果你觉得每次连接前都要先建SSH隧道太麻烦,尤其是用Navicat、DBeaver这类图形化工具时,直接开放3306端口也是一种选择,但要记住,开放3306端口意味着你的数据库直接暴露在公网,暴力破解和扫描攻击会随之而来。
修改bind-address并重启MySQL
找到MySQL配置文件,将bind-address = 127.0.0.1注释掉或改成0.0.0,然后重启MySQL:
systemctl restart mysqld
重启后,用netstat -tlnp | grep 3306检查,看到0.0.0:3306就说明MySQL已经在监听所有网络接口了。
创建允许任意IP连接的数据库账号
不同于SSH隧道方式,直接连接时MySQL看到的来源地址是你的真实IP,所以账号授权需要加上远端IP:
CREATE USER 'remote_user'@'%' IDENTIFIED BY '强密码'; GRANT ALL PRIVILEGES ON 你的数据库名. TO 'remote_user'@'%'; FLUSH PRIVILEGES;
表示匹配任意IP,出于安全考虑,更稳妥的做法是把替换成你的具体公网IP,例如'remote_user'@'123.45.67.89'。
用图形化工具连接的配置示例
以Navicat为例,新建连接时填写:
- 主机:你的服务器公网IP
- 端口:3306
- 用户名:remote_user
- 密码:你设置的密码
点击测试连接,成功后就完成了,DBeaver、MySQL Workbench的配置逻辑完全一致,只是界面字段位置略有不同。
连接报错排查:从2003到1045的常见问题
直接访问服务器上的mysql数据库时,报错信息基本能直接指向问题根源,这里列出最常见的三种。
2003 – Can’t connect to MySQL server
这个错误表示网络层面就没通,排查顺序:
- 在本地执行
ping 服务器IP,确认服务器在线 - 用
telnet 服务器IP 3306测试端口是否可达,不通就检查防火墙和安全组 - 确认MySQL确实在监听0.0.0.0,而不是127.0.0.1
1045 – Access denied for user
这个错误表示网络通了,但账号授权不匹配,检查:
-
用户名和密码是否拼写正确
- 账号允许的来源IP是否覆盖了你当前的IP
- 是否执行了
FLUSH PRIVILEGES
1130 – Host is not allowed to connect
这个错误明确告诉你当前主机IP没有权限,最直接的解决办法就是执行前面提到的'remote_user'@'%'授权,或者把IP换成你的实际IP。
公网直接连接的安全加固方案
如果你决定使用3306直连方式,必须做以下四层防护,否则相当于把数据库裸奔在公网上。
第一层:强密码策略,密码至少16位,包含大小写字母、数字和特殊符号,避免使用123456、root这类弱密码,MySQL 8.0自带密码校验组件,可以强制推行复杂度规则:
INSTALL COMPONENT 'file://component_validate_password'; SET GLOBAL validate_password.policy = 2;
第二层:指定来源IP白名单,无论安全组还是MySQL账号授权,都只放行你的固定IP,如果IP不固定,优先改用SSH隧道方案。
第三层:修改默认端口,把3306改成不常用的端口,例如13306,可以在一定程度上减少扫描器的命中率,修改方法是在配置文件里加一行port=13306,重启MySQL后生效。
第四层:降低账号权限,远程连接账号尽量只授予所需数据库的SELECT、INSERT、UPDATE、DELETE权限,不要直接给ALL PRIVILEGES,这样即使账号泄露,损失也在可控范围内。
本地无法访问而服务器上正常的话怎么排查
有一种比较常见的场景是:你在服务器本机用mysql -u root -p能正常登录,但本地电脑怎么连都不通,这种情况下问题几乎不在MySQL本身,而在网络链路。
按顺序检查:
- 防火墙:在服务器执行
iptables -L -n查看规则,如果看到DROP或REJECT相关的3306规则,用iptables -D INPUT 规则编号删除 - 云安全组:登录云厂商控制台,查看安全组入站规则,确认放行了你本地IP的3306端口
- 路由器或公司网络:部分办公网络会封锁非标准端口的外部连接,可以尝试用手机热点测试
- MySQL日志:查看
/var/log/mysql/error.log,如果里面出现Aborted connection相关的记录,说明连接到达了MySQL但被拒绝,那问题就在授权层面
访问MySQL数据库时的常用运维命令整理
无论用哪种方式连上了,以下几个命令在远程维护时几乎必用。
查看所有数据库:
SHOW DATABASES;
切换数据库:
USE 数据库名;
查看当前账号权限:
SHOW GRANTS;
查看MySQL版本:
SELECT VERSION();
查看所有连接来源:
SHOW PROCESSLIST;
这些命令不区分连接方式,SSH隧道和3306直连都能正常执行,建议你把它们存在本地笔记里,日后用得着。
服务器上mysql数据库访问方式的适用场景怎么选
怎么访问服务器上的mysql数据库这个问题,答案不是唯一的。不同场景有不同倾向。
- 如果你使用的是云服务器,且数据库只给少数几个固定的开发人员用,SSH隧道是更稳妥的选择,成本是每次连接前多一条命令,但换来的是端口封闭和加密传输。
- 如果你需要频繁用图形化工具查看数据,而且服务器安全组可以锁定来源IP,那3306直连更高效。
- 如果你的数据库服务于线上应用(比如网站后端),那应用本身应该通过内网连接,而不是走公网,此时你访问数据库只是为了维护,建议用SSH隧道,应用连接则走云厂商的内网地址。
行业共识认为,公网环境下没有任何理由直接暴露MySQL的默认端口,即便你选择了3306直连,也务必加上IP白名单和强密码。
远程访问MySQL数据库前与后的完整动作
最后梳理一次完整流程,方便你对照执行。
连接前:
- 确认MySQL服务运行中
- 确认bind-address已改为0.0.0.0或以注释形式放行
- 确认防火墙和安全组放行3306(如果走SSH隧道则不需要)
- 确认账号授权覆盖了你的来源IP
连接后:
- 用
SHOW GRANTS验证权限范围 - 用
SELECT USER(), CURRENT_USER();确认当前身份 - 操作结束后及时退出连接,命令行用
exit,图形化工具直接关闭连接
常见问题解答
为什么通过SSH隧道连接时MySQL报错说无法从localhost连接?
因为SSH隧道在服务器上建立了一个本地回环连接,MySQL会把这条连接识别为来自localhost,而你的账号授权里没有包含localhost,所以被拒绝,解决办法是登录服务器执行GRANT ALL PRIVILEGES ON 数据库名. TO '用户名'@'localhost' IDENTIFIED BY '密码';,然后刷新权限。
云服务器上安全组已经放行3306还是连不上怎么办?
请先检查服务器系统防火墙是否放行,云安全组和系统防火墙是两层独立的机制,任何一层拦截都会导致连接失败,在服务器上执行systemctl status firewalld确认防火墙状态,然后执行firewall-cmd --add-port=3306/tcp --permanent && firewall-cmd --reload放行,最后用telnet 服务器IP 3306从本地测试,能通就说明网络路径正常。
直接用root远程登录MySQL可取吗?
不太建议,MySQL的root账号拥有所有权限,一旦被暴力破解,整台服务器和所有数据库都会沦陷,正确的做法是创建独立的远程账号,只授予工作所需的最小权限,如果你确实需要root级别的管理操作,建议先SSH登录到服务器,再通过本机socket连接MySQL执行管理任务,远程连接用的账号,权限越少越安全。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/769625.html





