必须设成具体内网ip(如192.168.10.5),不能用0.0.0.0或127.0.0.1;需确保该ip在服务器上真实存在、配置无引号、重启mysqld后netstat验证监听正确,并同步删除'%'账号、精确授权用户、放行内网防火墙及云安全组。

MySQL bind-address 必须设成具体内网 IP,不能写 0.0.0.0 或 127.0.0.1
设成 0.0.0.0 就等于把所有网卡(包括外网、Docker bridge、K8s CNI)全暴露出去;设成 127.0.0.1 则其他内网机器根本连不上——这不是“内网访问”,是“仅本机访问”。
真正起作用的是你服务器上实际分配的内网地址,比如 192.168.10.5 或 172.16.0.12,必须和 ip addr show 输出里对应网卡的 inet 地址完全一致。
常见错误:bind-address = 192.168.10.* 或 bind-address = eth0 —— MySQL 不支持通配符或网卡名,只认 IPv4/IPv6 字面量地址。
修改 my.cnf 后必须重启 mysqld,且要验证 netstat 结果
编辑配置文件(通常是 /etc/my.cnf 或 /etc/mysql/my.cnf),在 [mysqld] 段下写入:bind-address = 192.168.10.5
保存后执行:systemctl restart mysqld
然后立刻验证:netstat -tlnp | grep :3306
正确输出应为:tcp 0 0 192.168.10.5:3306 0.0.0.0:* LISTEN
如果还是显示 0.0.0.0:3306 或 *:3306,说明配置没生效——可能改错了文件、没加 [mysqld] 段、或被其他配置覆盖(如 /etc/mysql/conf.d/ 下的文件)。
用户权限 host 字段必须精确匹配,且要删掉 % 账号
即使 bind-address 正确了,只要存在 'app'@'%' 这类账号,外网机器只要能路由到那个端口(比如防火墙开了 3306),照样能连进来。
必须做三件事:
- 用
SELECT User, Host FROM mysql.user WHERE User = 'app';查出所有同名账号 - 删掉所有带
'%'或宽泛通配符的记录,例如DROP USER 'app'@'%'; - 重建账号时指定确切来源 IP:
CREATE USER 'app'@'192.168.10.42' IDENTIFIED BY 'xxx'; - 执行
FLUSH PRIVILEGES;生效
'app'@'192.168.10.%' 看似安全,实则会匹配 192.168.10x.y 这类非法地址,不推荐。防火墙必须同步放行内网段,否则连通性直接失败
Linux 上仅靠 bind-address 和权限控制不够。如果服务器开了 firewalld 或 ufw,外网虽连不到,但内网机器也可能被拦在第一层。
以 firewalld 为例:firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" port port="3306" protocol="tcp" accept'firewall-cmd --reload
云服务器(阿里云、腾讯云等)务必检查安全组规则,禁止 0.0.0.0/0,只添加内网 CIDR 段。
别忘了:容器或 K8s 环境里,客户端看到的源 IP 可能是 Service VIP 或 Node IP,得结合 SHOW PROCESSLIST; 确认真实 Host 列值再配权限。











