bind-address设为127.0.0.1是最稳妥的本地锁死方式,mysql仅监听回环接口,内核直接拒绝所有网卡tcp请求;但需避免配置localhost、与skip-networking共存、未重启服务,并通过ss -tlnp确认监听地址确为127.0.0.1:3306。

bind-address 设成 127.0.0.1 是最稳妥的本地锁死方式
只要 MySQL 实际监听地址是 127.0.0.1:3306,内核会直接拒绝所有来自网卡的 TCP 连接请求,包括本机用 mysql -h 192.168.1.100 -u root -p 这种走公网 IP 的连接——它根本到不了 MySQL 进程。
常见翻车点:
-
bind-address = localhost→ 启动失败,报错Can't start server: Bind on TCP/IP port,MySQL 不识别字符串localhost - 配置里同时存在
skip-networking = 1和bind-address = 127.0.0.1→skip-networking优先级更高,TCP 完全关闭,mysqldump、远程管理工具全失效 - 改完没重启:执行
sudo systemctl restart mysql(或mariadb),否则配置不生效
验证是否真生效:运行 ss -tlnp | grep :3306,输出应只含 127.0.0.1:3306,不能出现 *:3306 或 0.0.0.0:3306。
bind-address 设成内网 IP(如 192.168.1.100)必须满足三个硬条件
这适合多网卡服务器,想让 PHP 应用服务器直连 MySQL,又不想改应用里的 host 配置。
缺一不可:
-
bind-address = 192.168.1.100(不能带空格、引号、括号;写成"192.168.1.100"会导致 MySQL 启动失败,日志报Invalid argument) - 对应网卡已启用且该 IP 已配置:运行
ip addr show能查到该 IP,且状态为UP - 防火墙放行该网卡的 3306 端口:CentOS 的
firewalld默认只信任publiczone,若内网网卡在internalzone,需显式执行firewall-cmd --zone=internal --add-port=3306/tcp --permanent
典型误判场景:DNS 解析把应用连的域名指向了公网 IP,结果连不上——这不是 MySQL 配置问题,得改 DNS 或 /etc/hosts。
bind-address = 0.0.0.0 不等于“开放给所有人”
它只是告诉 MySQL:“我在所有网卡上监听 3306”,但后续还有三道过滤关卡:
- 系统防火墙(
iptables/firewalld)是否放行该端口和源 IP - MySQL 用户权限表中,
'user'@'host'的host字段是否允许那个 IP(例如'app'@'10.0.2.%') - 云平台安全组(阿里云/腾讯云)是否放开 3306 入方向规则
所以即使 bind-address = 0.0.0.0,只要防火墙默认 DROP 所有入向 3306 流量,外网依然连不上。但风险在于:一旦防火墙规则被误删或绕过,服务就彻底裸奔。
别忽略容器和云环境下的监听范围陷阱
在 Docker 或 Kubernetes 中,bind-address = 127.0.0.1 只对容器内部有效。宿主机、其他 Pod 或 Service 仍可能通过桥接网络(如 docker0)或 ClusterIP 访问到 MySQL 容器的 3306 端口。
此时必须额外做两件事:
- 容器启动时加
--network host(不推荐)或明确指定--publish 127.0.0.1:3306:3306绑定到宿主机回环 - 配合
NetworkPolicy(K8s)或docker network create --driver bridge自定义隔离网络,禁止跨网段访问
云数据库(如 RDS)通常不暴露 bind-address 配置项,限制访问只能靠安全组 + 白名单用户 + VPC 网络策略,bind-address 在这类场景下完全不可控。











