MySQL 默认端口是否被防火墙拦截?
安装完 MySQL 后,远程连接失败,大概率是系统防火墙(如
firewalld或
ufw)默认拒绝了
3306端口。Linux 发行版通常不自动放行数据库端口,哪怕 MySQL 服务本身已正常启动。
验证方式:在服务器本地执行
telnet 127.0.0.1 3306能通,但从外部机器
telnet your_server_ip 3306超时,基本可锁定为防火墙问题。 CentOS/RHEL 8+(
firewalld):
sudo firewall-cmd --permanent --add-port=3306/tcp,然后
sudo firewall-cmd --reloadUbuntu/Debian(
ufw):
sudo ufw allow 3306/tcp若使用云服务器(如阿里云、AWS),安全组规则必须单独配置,系统防火墙放开后仍连不上,优先查安全组
只允许特定 IP 访问 MySQL 端口
开放
3306给所有 IP 是高危操作。生产环境应限制来源 IP,尤其当 MySQL 绑定到公网地址(
bind-address = 0.0.0.0)时。
防火墙层面比 MySQL 用户权限更前置——它能直接拦截非法连接请求,避免认证爆破尝试到达数据库进程。
firewalld:用
--source指定网段,例如
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" port port="3306" protocol="tcp" accept'
ufw:
sudo ufw allow from 203.0.113.5 to any port 3306 proto tcp注意:MySQL 用户的
host字段(如
'user'@'192.168.10.%')和防火墙规则是两层控制,建议两者都设窄
MySQL 自身 bind-address 配置影响防火墙效果
即使防火墙放行了
3306,如果 MySQL 的
bind-address设置为
127.0.0.1(默认值之一),它根本不会监听外部网络接口,防火墙规则再宽松也无用。
检查当前绑定地址:
sudo ss -tlnp | grep :3306,若只显示
127.0.0.1:3306,说明 MySQL 拒绝外部连接是自身配置导致,不是防火墙问题。 修改
/etc/mysql/mysql.conf.d/mysqld.cnf(Debian/Ubuntu)或
/etc/my.cnf(RHEL/CentOS)中的
bind-address设为
0.0.0.0表示监听所有 IPv4 接口;更安全的做法是写具体内网 IP,如
192.168.1.100改完必须重启 MySQL:
sudo systemctl restart mysql(或
mariadb)
是否需要关闭防火墙?
不需要,也不应该。关闭
firewalld或
ufw会暴露 SSH、HTTP 等其他服务,风险远大于只开
3306端口。
真正要关的是“没用的默认开放策略”。比如某些云镜像预装了
ufw但未启用,而另一些则默认
deny所有入站——此时你不是要关它,而是明确告诉它“只准谁连 MySQL”。
一个常被忽略的点:Docker 容器运行 MySQL 时,宿主机防火墙规则依然生效,且容器端口映射(
-p 3306:3306)不绕过宿主机 iptables/firewalld。容器场景下,既要配容器网络,也要配宿主机防火墙。
