必须先确认mysql服务active(running)且ss -tlnp | grep :3306输出*:3306或0.0.0.0:3306;若仅127.0.0.1:3306则需修改my.cnf中bind-address为0.0.0.0并重启服务。

确认 MySQL 确实监听 3306 且不限于本地
很多连接失败根本不是防火墙问题,而是 mysqld 自己没对外暴露。先别动防火墙,执行这两条命令:
-
systemctl status mysqld—— 必须看到 active (running) -
ss -tlnp | grep :3306—— 输出里得有*:3306或0.0.0.0:3306,如果只有127.0.0.1:3306,说明my.cnf里写了bind-address = 127.0.0.1,得改成0.0.0.0并systemctl restart mysqld
firewalld 放行 3306 端口(CentOS/RHEL 7+ / 麒麟等)
用 firewall-cmd 是主流做法,但容易错在「临时 vs 永久」和「重载遗漏」:
- 永久生效必须加
--permanent:firewall-cmd --add-port=3306/tcp --permanent - 加完不
--reload就等于没加:firewall-cmd --reload - 验证是否真生效:
firewall-cmd --list-ports应该输出3306/tcp - 别用
--add-service=mysql—— 这个 service 在多数系统里压根没定义,或绑错端口,硬写3306/tcp最稳
iptables 直接编辑规则(旧系统 / Ubuntu 16.04 及更早)
如果你的系统还在用 iptables(比如某些 CentOS 6 或定制版 Linux),改配置文件比命令更可靠:
- 编辑
/etc/sysconfig/iptables,在最后一行REJECT之前插入:-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT - 顺序很重要:这条规则必须在
-j REJECT或-j DROP之前,否则永远不生效 - 保存后重启服务:
service iptables restart(不是 reload) - Ubuntu 用户若用
ufw,直接跑ufw allow 3306/tcp即可,不用碰 iptables
连不上?优先排查这三个非防火墙环节
90% 的“防火墙已开却连不上”问题,其实卡在下面这三处:
-
mysql用户权限没开远程:执行GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password';后必须FLUSH PRIVILEGES; - 云服务器(如阿里云、腾讯云)有**安全组**,它比系统防火墙还外一层,必须单独放行 3306/tcp
- 客户端用错地址:本地测试别用
127.0.0.1,要用服务器真实内网或公网 IP;telnet server_ip 3306或nc -zv server_ip 3306能通,才说明网络层没问题
防火墙只是其中一环,真正卡住的地方往往在 MySQL 绑定地址、用户 host 限制、或者云平台的安全组——这三处漏查一个,光开 3306 端口也没用。











