mysql连接失败主因是防火墙未放行或规则冲突,需同步检查bind-address、iptables/nftables、云安全组、conntrack超时及selinux/apparmor五层配置。

MySQL 默认端口被扫描或连接拒绝怎么办
直接开 3306 端口对外等于把锁孔焊死前先递钥匙。绝大多数生产环境的 MySQL 连接失败,不是配置错,是防火墙根本没放行或规则写反了。
Linux 上用 iptables 或 nftables 控制流量,Windows 用系统防火墙,云服务器还得过安全组这一关——三者不一致,就必然出问题。
- 检查当前监听状态:
netstat -tlnp | grep :3306,确认 MySQL 确实在跑且绑定的是127.0.0.1还是0.0.0.0 - 只允许特定 IP 访问时,
iptables规则必须写在INPUT链开头(靠前优先),否则可能被后面的DROP拦住 - 云平台(如阿里云、腾讯云)的安全组默认拒绝所有入向流量,
3306必须显式添加,且源 IP 建议用最小范围(比如192.168.1.100/32),别写0.0.0.0/0
MySQL 绑定地址和防火墙规则怎么配才不冲突
常见错误是 MySQL bind-address 设成 127.0.0.1,但防火墙却放开 3306 给外网——结果就是“端口通了,连不上”。两者必须对齐。
my.cnf 中的 bind-address 决定 MySQL 听谁,防火墙决定谁有资格敲门。听 127.0.0.1 就只能本地连;听 0.0.0.0 才可能被远程连,但此时防火墙必须同步放行对应来源。
- 本地开发:设
bind-address = 127.0.0.1,防火墙可完全关闭3306入向规则 - 内网服务(如 PHP 应用在同一局域网):设
bind-address = 192.168.1.0/24或0.0.0.0,防火墙加-s 192.168.1.0/24 -p tcp --dport 3306 -j ACCEPT - 绝对禁止
bind-address = 0.0.0.0+ 安全组开放0.0.0.0/0,这是线上最常被爆破的组合
连接超时或被重置?可能是防火墙的连接跟踪机制在作怪
MySQL 空闲连接常被防火墙的 conntrack 表踢掉,现象是客户端突然报 Lost connection to MySQL server during query 或 Connection reset by peer,但 MySQL 日志里查不到异常。
Linux 默认的连接跟踪超时很短(如 TCP established 状态仅 5 天,但某些发行版或云主机内核会调得更激进),而 MySQL 的 wait_timeout 和 interactive_timeout 又比它长,就会出现“MySQL 还以为连着,防火墙早删了连接记录”的错位。
- 查当前 conntrack 超时值:
sysctl net.netfilter.nf_conntrack_tcp_timeout_established - 临时调大(比如设为 86400 秒):
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400 - 永久生效需写入
/etc/sysctl.conf,且注意重启后是否被云厂商的 init 脚本覆盖 - 更稳妥的做法是客户端加连接池并启用
ping或autoReconnect=true(JDBC)等保活机制,别全指望防火墙
SELinux 或 AppArmor 开启时,MySQL 连不上防火墙也放行了?
CentOS/RHEL 的 SELinux 或 Ubuntu 的 AppArmor 是独立于 iptables 的访问控制层,哪怕端口通、bind 地址对、用户密码都正确,也可能被拦截,错误日志通常出现在 /var/log/audit/audit.log 或 dmesg 输出里,关键词是 avc: denied。
这类问题不会报 MySQL 错误,也不会显示在 iptables -L 里,排查路径容易断掉。
- 临时关闭 SELinux 测试:
setenforce 0(别改config文件,避免重启失效) - 查看是否是 SELinux 拦截:
ausearch -m avc -ts recent | grep mysqld - 放行网络连接:
setsebool -P mysqld_can_network_connect 1 - AppArmor 用户检查
/etc/apparmor.d/usr.sbin.mysqld是否包含network inet stream,这一行











