MySQL连接失败:防火墙未放行3306端口怎么办

陆景行
陆景行
发布时间:2026-09-22 | 3人浏览过
原创

MySQL在服务器本机可以正常连接,但从另一台电脑访问时一直超时,一个常见原因就是服务器防火墙没有允许TCP 3306端口通过。处理这类问题时,不建议一上来就关闭整个防火墙,而应该先确认MySQL确实在监听3306,再检查防火墙规则,最后只向需要访问数据库的IP开放端口。

需要注意,开放防火墙只是MySQL远程连接链路中的一环。如果MySQL只监听127.0.0.1、账号没有远程登录权限,或者云服务器安全组没有放行3306,即使服务器防火墙已经配置正确,远程连接仍然会失败。

一、先判断是不是3306端口被防火墙拦住

出现下面这些情况时,可以重点检查防火墙:

  • 在MySQL服务器本机执行客户端命令可以登录数据库;
  • 远程连接使用的服务器IP和端口没有写错;
  • 远程客户端长时间等待后提示连接超时;
  • 服务器能够正常被Ping通,或者SSH等其他服务可以访问;
  • MySQL服务已经启动,但外部无法访问3306端口。

典型报错可能是:

ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.1.10:3306'

不过,ERROR 2003并不能单独证明就是防火墙问题。端口没有监听、网络路由异常和安全组拦截等情况,同样可能产生类似表现。因此正确的排查顺序应该是从服务器内部逐层向外检查。

MySQL连接失败:防火墙未放行3306端口怎么办
图1:MySQL远程连接失败时,建议按照服务、监听端口、防火墙、外部网络策略和账号权限的顺序排查。

二、确认MySQL是否真的在监听3306端口

在修改防火墙之前,先登录MySQL所在的Linux服务器。可以使用下面的命令查看3306端口:

ss -lntp | grep 3306

如果系统没有显示进程信息的权限,可以使用root身份执行:

sudo ss -lntp | grep 3306

可能看到类似下面的结果。

示例输出:

LISTEN 0 151 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=21))

这里最值得注意的是监听地址。

监听结果 含义
0.0.0.0:3306 监听服务器所有IPv4接口,具备接受外部TCP连接的条件。
127.0.0.1:3306 只监听本机回环地址,远程机器无法直接连接。
192.168.1.10:3306 只监听指定网卡地址,需要通过对应地址访问。

如果执行命令完全没有输出,那么问题很可能不在防火墙,而是MySQL没有运行、使用了不同端口,或者没有建立TCP监听。

可以继续检查服务状态。例如使用systemd管理MySQL的服务器上,可以尝试:

sudo systemctl status mysql

部分发行版或安装方式使用的服务名称可能是:

sudo systemctl status mysqld
只有确认MySQL已经监听3306之后,开放3306防火墙端口才有意义。否则防火墙即使完全放行,远程客户端也没有可以连接的MySQL进程。

三、使用firewalld放行MySQL的3306端口

如果服务器使用firewalld,可以先查看服务是否正在运行:

sudo firewall-cmd --state

正常运行时通常会得到:

示例输出:

running

还可以查看当前活动的zone:

sudo firewall-cmd --get-active-zones

下面假设服务器网卡位于public区域。如果实际使用的是其他zone,应将命令中的public替换成实际名称。

临时开放3306

sudo firewall-cmd --zone=public --add-port=3306/tcp

这种方式适合排查问题,但规则通常不会在firewalld重新加载或服务器重启之后继续保留。

永久开放3306

sudo firewall-cmd --zone=public --permanent --add-port=3306/tcp
sudo firewall-cmd --reload

然后确认规则是否已经存在:

sudo firewall-cmd --zone=public --list-ports

示例输出:

22/tcp 80/tcp 443/tcp 3306/tcp

只要列表中出现3306/tcp,说明这一层的firewalld端口规则已经加入。

MySQL连接失败:防火墙未放行3306端口怎么办
图2:使用firewalld开放3306端口时,应确认实际zone并在修改后重新加载和验证规则。

四、Ubuntu或Debian使用UFW时怎么开放3306

如果服务器使用UFW,可以先检查状态:

sudo ufw status

如果显示:

Status: active

说明UFW正在工作。

直接允许所有来源访问3306可以执行:

sudo ufw allow 3306/tcp

然后检查规则:

sudo ufw status numbered

示例输出:

[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 3306/tcp                   ALLOW IN    Anywhere

如果数据库只需要给一台应用服务器使用,更推荐限制来源IP。例如应用服务器地址是203.0.113.20,可以写成:

sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp

这种规则表示:只有来源地址为203.0.113.20的主机才能连接本机TCP 3306端口。

示例中的IP只是演示。实际配置时,应替换为真正需要连接MySQL的应用服务器、办公网络出口或管理主机IP。不要机械复制示例地址。

五、生产服务器不建议把3306直接开放给整个互联网

为了排查问题,把3306临时开放给所有来源确实简单,但如果MySQL只服务于固定的Web服务器或业务服务器,更合理的做法是采用IP白名单。

连接关系可以理解为:

MySQL连接失败:防火墙未放行3306端口怎么办
图3:固定应用服务器访问MySQL时,可以只允许指定来源IP访问3306,减少数据库直接暴露在公网的范围。

例如在firewalld中,可以使用rich rule限制来源IP。假设只允许203.0.113.20:

sudo firewall-cmd --zone=public --permanent \
  --add-rich-rule='rule family="ipv4" source address="203.0.113.20" port protocol="tcp" port="3306" accept'

sudo firewall-cmd --reload

查看规则:

sudo firewall-cmd --zone=public --list-rich-rules

如果此前已经添加过允许所有来源访问3306的规则,而现在准备改成白名单方式,可以删除原来的公共端口规则:

sudo firewall-cmd --zone=public --permanent --remove-port=3306/tcp
sudo firewall-cmd --reload

这里需要注意规则设计:如果既存在“允许所有来源访问3306”的规则,又增加了一条指定IP白名单,那么白名单并没有真正达到限制所有其他来源的目的。

六、防火墙开放以后,怎么验证3306已经能够访问

不要只根据配置命令返回成功就判断问题已经解决。最好从真正需要访问MySQL的客户端机器上测试TCP连接。

Linux或macOS上可以使用nc:

nc -vz 192.168.1.10 3306

连接成功时的示例输出可能类似:

Connection to 192.168.1.10 port 3306 [tcp/mysql] succeeded!

如果是Windows PowerShell,可以使用:

Test-NetConnection 192.168.1.10 -Port 3306

重点查看:

TcpTestSucceeded : True

TCP端口确认可以访问以后,再测试真正的MySQL登录:

mysql -h 192.168.1.10 -P 3306 -u appuser -p

这样可以把“网络端口问题”和“MySQL登录权限问题”分开。

七、3306已经放行,但MySQL还是连接不上怎么办

如果外部端口测试仍然失败,就不能只盯着Linux防火墙。一次完整的远程MySQL连接,通常要经过多个环节。

1. 检查MySQL是否只监听127.0.0.1

再次执行:

sudo ss -lntp | grep 3306

如果看到:

127.0.0.1:3306

说明MySQL只接受本机连接。此时需要检查当前MySQL实例使用的配置文件以及与监听地址相关的配置,而不是继续添加防火墙规则。

不同Linux发行版、MySQL安装来源和版本的配置文件位置可能不同,因此不建议在不了解当前环境的情况下直接照搬某一个文件路径。可以先通过MySQL实际配置和启动参数确认正在使用的配置文件,再修改对应设置。

2. 检查云服务器安全组或上游防火墙

如果MySQL部署在云服务器上,通常还会有独立于Linux系统防火墙之外的网络访问控制,例如安全组、云防火墙或访问控制列表。

这时即使执行:

sudo firewall-cmd --zone=public --list-ports

已经明确显示3306/tcp,外部连接仍可能被云平台入口规则拦截。

需要到服务器所属平台的网络安全配置中检查TCP 3306入站规则。同样建议只允许实际需要连接数据库的来源IP,而不是默认允许整个互联网访问。

3. TCP能够连接,但MySQL提示Access denied

如果端口测试已经成功,例如:

nc -vz 192.168.1.10 3306

能够连接,但MySQL客户端返回类似:

ERROR 1045 (28000): Access denied for user ...

这通常已经不是防火墙问题,而应该检查MySQL账号、密码以及账号允许连接的Host范围。

可以登录MySQL后查看相关账号配置,例如:

SELECT User, Host
FROM mysql.user
WHERE User = 'appuser';

示例结果:

+---------+----------------+
| User    | Host           |
+---------+----------------+
| appuser | 203.0.113.20   |
+---------+----------------+

这表示该账号的Host范围是指定地址。实际权限应根据业务需要设置,不建议为了省事就把所有数据库账号都改成任意来源可登录。

八、不要通过直接关闭防火墙来长期解决问题

排障时有人会执行停止防火墙的命令,然后发现MySQL立刻可以连接,由此确认问题所在。这种方法可以作为短暂的定位手段,但不适合作为正式解决方案。

例如firewalld环境中直接停止整个防火墙:

sudo systemctl stop firewalld

会影响的不只是3306,而是整台服务器的主机防火墙保护。原本没有对外开放的服务,也可能因此失去这一层访问控制。

更合理的处理方式是明确下面三个条件:

  • 需要开放的协议:TCP;
  • 需要开放的端口:3306;
  • 允许访问的来源:业务服务器或可信网络的IP。

确定这三个条件后添加精确规则,比直接关闭防火墙更容易维护,也能减少不必要的网络暴露。

九、完整排查过程总结

MySQL连接失败:防火墙未放行3306端口怎么办
图4:根据实际表现判断问题所在,可以避免把所有MySQL连接失败都误认为是3306防火墙问题。

遇到“MySQL连接失败,怀疑防火墙没有放行3306”时,可以按照下面的顺序处理:

  1. 在数据库服务器本机确认MySQL服务正常运行;
  2. 通过ss -lntp | grep 3306确认3306正在监听,并检查监听地址;
  3. 确认服务器使用的是firewalld、UFW还是其他防火墙方案;
  4. 在对应防火墙中开放TCP 3306,生产环境优先限制来源IP;
  5. 如果使用云服务器,再检查云安全组、云防火墙或其他上游访问控制;
  6. 从真正的客户端机器测试3306 TCP连接;
  7. 端口能够访问后,再使用MySQL客户端检查账号密码和Host授权。

这套排查方法的关键,是把“3306端口能不能到达”和“MySQL允不允许登录”分开判断。前者属于网络、防火墙和监听配置问题,后者主要属于MySQL账号与权限问题。按照链路逐层检查,通常比反复修改配置或者直接关闭防火墙更容易找到真正的故障点。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表