MySQL启动失败时先查127.0.0.1是否被iptables拦住,因mysqld启动需自检127.0.0.1:3306,若INPUT链未显式放行该流量(如iptables -A INPUT -s 127.0.0.1 -p tcp --dport 3306 -j ACCEPT),服务将卡住超时,日志仅显示“Can’t connect to local MySQL server”。

MySQL启动失败时先查127.0.0.1是否被iptables拦住
MySQL服务启动卡住、systemctl start mysql超时、日志只显示Can’t connect to local MySQL server,大概率是iptables INPUT链没放行本地回环。mysqld启动时会主动连接127.0.0.1:3306做自检,这条流量必须显式允许。
错误写法:iptables -A INPUT -p tcp --dport 3306 -j ACCEPT(没限定源地址,后续DROP规则可能覆盖)
正确写法(必须放在所有拒绝规则之前):iptables -A INPUT -s 127.0.0.1 -p tcp --dport 3306 -j ACCEPT
-
-s 127.0.0.1不能省略,否则规则不精准,容易被后续! -s类条件误匹配 - 别写成
!-s或!- s,空格缺失会导致语法错误,规则无效 - 这条规则要插在
DROP之前,iptables按顺序匹配,命中即停
ufw配置3306白名单时必须显式放开lo接口
ufw默认策略是“入向全部拒绝”,但它对lo(本地回环)接口不生效——因为lo流量不走ufw主规则链。结果就是:ufw开了3306,MySQL还是起不来。
必须补这一句:ufw allow in on lo
再加业务白名单,例如:ufw allow from 192.168.1.50 to any port 3306 proto tcp
- 别用
ufw allow 3306/tcp——这是放行所有来源,极度危险 - 启用前用
ufw status verbose确认输出里有Anywhere on eth0类条目,而不仅是127.0.0.1 - 最后别漏
ufw enable,否则规则不激活
云服务器上安全组和iptables谁先拦包
阿里云、腾讯云、AWS的安全组是网络层第一道过滤,数据包根本没进操作系统就可能被丢弃。iptables/ufw规则再细,安全组没开3306,telnet公网IP 3306必然不通。
排查顺序必须是:
① 外网执行telnet your-public-ip 3306 → 不通?查安全组
② 服务器本机执行nc -zv 127.0.0.1 3306和nc -zv 192.168.1.50 3306 → 响应不一致?说明iptables/ufw规则没对齐
- 生产环境建议双控:安全组只放运维跳板机和应用服务器内网段,iptables/ufw再做一层IP校验
- 安全组规则删了没人提醒,iptables若已保存(如
iptables-save > /etc/iptables/rules.v4),重启后还在——这点常被忽略
bind-address和防火墙规则必须对齐
即使iptables放行了3306,如果MySQL的bind-address = 127.0.0.1,它只监听本地,外部连接永远失败。反过来,bind-address = 0.0.0.0但防火墙没限制来源IP,等于把数据库裸奔暴露。
检查当前监听地址:ss -tlnp | grep :3306
常见配置组合:
- 仅本机访问:
bind-address = 127.0.0.1+ 不配防火墙规则(最安全) - 内网访问:
bind-address = 192.168.1.100+ iptables/ufw只放行192.168.1.0/24 - 严禁
bind-address = 0.0.0.0+ufw allow 3306/tcp这种宽泛组合
规则顺序、本地回环、安全组、bind-address,四者只要一个错位,3306就不可靠。最容易被忽略的是MySQL自检依赖127.0.0.1这条路径,它不像业务连接那么直观可测。


















