mysql本身无bind-address白名单功能,仅支持单地址监听;真ip白名单需协同用户host字段限制、防火墙规则(ufw/iptables)及云安全组,四层防护缺一不可。

MySQL 本身没有 bind-address 白名单功能,bind-address 只能指定一个监听地址,不是“允许多个IP”的白名单机制。真要实现 IP 白名单,必须配合用户 Host 限制 + 防火墙规则。
bind-address 不是白名单,只是单地址监听开关
很多人误以为 bind-address 设成多个 IP 就能“白名单”,但 MySQL 官方明确不支持多值:bind-address 是字符串类型,只接受单个 IPv4/IPv6 地址、0.0.0.0、127.0.0.1 或 *(MySQL 5.7+ 默认值)。设成 192.168.1.10 后,MySQL 只在该网卡上收包,其他 IP 的连接请求连 TCP 握手都进不来——但这不是白名单,是网络层屏蔽。
常见错误现象:
- 设了
bind-address = 192.168.1.10,但服务器有双网卡(如还有一张公网网卡),结果从公网仍能连上 → 实际是bind-address没生效,可能被配置文件多处覆盖或未重启 mysqld - 设成
0.0.0.0后加防火墙,却忘了关掉云平台安全组 → 外网仍可连,误以为防火墙失效
真正起白名单作用的是 mysql.user 表的 Host 字段
MySQL 权限系统判断“谁可以连”,靠的是 user@host 这个组合。Host 字段支持精确 IP、子网(如 '192.168.1.%')、域名,但不支持 CIDR(如 192.168.1.0/24)。
实操建议:
- 禁止用
'user'@'%',哪怕临时测试也别留着 - 允许多个固定 IP,就建多个同名用户:比如
'app'@'10.0.1.5'、'app'@'10.0.1.6',再分别GRANT - 改已有用户 Host:用
RENAME USER 'old'@'%' TO 'old'@'10.0.1.5',而不是直接UPDATE mysql.user(易漏刷新) - 执行完一定要
FLUSH PRIVILEGES,否则内存权限缓存不会更新
ufw / iptables 必须补上,否则 bind-address 形同虚设
如果 bind-address = 0.0.0.0(默认或远程管理必需),仅靠用户 Host 控制等于裸奔:非法 IP 能完成 TCP 连接,再收到 “Access denied” 错误——这会暴露服务存在、用户名有效性,还浪费连接资源。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
用 ufw(Ubuntu)快速封死非白名单流量:
ufw reset ufw allow from 10.0.1.5 to any port 3306 ufw allow from 10.0.1.6 to any port 3306 ufw default deny incoming ufw enable
用 iptables(CentOS/RHEL)等效写法:
iptables -P INPUT DROP iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.5 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.6 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -j DROP
注意:云服务器(AWS/Azure/阿里云)必须同步配安全组,防火墙规则才真正生效。
验证是否生效的三步检查法
别只信配置文件,每次改完必须逐层验证:
- 查监听地址:
ss -tlnp | grep :3306看实际绑定的是不是你设的 IP(比如显示*:3306就是0.0.0.0,192.168.1.10:3306才对) - 查用户权限:
SELECT User, Host FROM mysql.user WHERE User = 'your_user';确认 Host 列没残留%或宽泛匹配 - 从白名单外 IP 实测:
mysql -u test -p -h your_server_ip应该卡在连接阶段(防火墙拦截)或秒报Access denied(权限拒绝),而不是超时
最容易被忽略的是:MySQL 重启后,systemd 有时会加载错误的配置文件(比如 /etc/my.cnf 和 /etc/mysql/mysql.conf.d/mysqld.cnf 冲突),导致 bind-address 设置静默失效。务必用 mysqld --verbose --help | grep "bind-address" 确认最终生效值。










