mysql 8.0 默认仅监听127.0.0.1,需修改bind-address为0.0.0.0或配合防火墙与用户host限制实现安全远程访问,并注意认证插件兼容性及云平台安全组放行。

MySQL 8.0 默认只监听本地,不改 bind-address 就连不通
云服务器上装完 mysql-server,systemctl is-active mysql 显示 active,不代表你能从公网连上。根本原因是 MySQL 进程默认只绑定 127.0.0.1,压根不接收外部 IP 的 TCP 请求。
必须编辑配置文件:/etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu/Debian)或 /etc/my.cnf(CentOS/RHEL),找到 bind-address = 127.0.0.1 这一行:
- 改成
bind-address = 0.0.0.0(允许所有 IP),或更安全地写成具体白名单网段,比如bind-address = 192.168.1.0/24(但注意:MySQL 本身不支持 CIDR 写法,该写法无效;真正生效的只有单 IP 或0.0.0.0) - 更推荐做法是保留
127.0.0.1,靠防火墙和用户权限做白名单——因为bind-address没法配多个 IP,也不支持子网匹配 - 改完务必执行
sudo systemctl restart mysql,再用sudo ss -tlnp | grep :3306确认监听的是*:3306,不是127.0.0.1:3306
创建用户时用 'user'@'xxx.xxx.xxx.xxx' 才算真白名单
MySQL 的用户账号是「用户名 + 来源 host」组成的元组,'myuser'@'%' 是通配所有 IP,等于没白名单;而 'myuser'@'203.123.45.67' 才是精确控制。
实操建议:
- 先登录:
sudo mysql(跳过密码验证,避免被caching_sha2_password卡住) - 创建带来源限制的用户:
CREATE USER 'appdb'@'203.123.45.67' IDENTIFIED BY 'StrongPass123!'; - 授权时也带上 host:
GRANT SELECT,INSERT,UPDATE ON myapp.* TO 'appdb'@'203.123.45.67'; - 如果要允许多个固定 IP,得重复执行
CREATE USER和GRANT,不能用逗号或数组语法 - 别忘了
FLUSH PRIVILEGES;,否则权限不加载进内存
云平台安全组和系统防火墙(ufw/iptables)必须同时放行 3306
即使 MySQL 听了 0.0.0.0:3306、用户也建对了,只要任一环节挡着,连接就超时。两个层面缺一不可:
- 云平台侧(如阿里云/腾讯云控制台):在「安全组规则」里添加入方向规则,协议类型选
TCP,端口范围填3306,源 IP 填你要放行的具体 IP(如203.123.45.67/32),不要填0.0.0.0/0 - 系统侧(Linux 防火墙):
sudo ufw allow from 203.123.45.67 to any port 3306(Ubuntu);CentOS 用sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.123.45.67" port port="3306" protocol="tcp" accept',然后 reload - 验证是否生效:
sudo ufw status verbose或sudo firewall-cmd --list-all,确认规则已加载
客户端连不上?先查 plugin 字段是不是 caching_sha2_password
很多老工具(Navicat ≤ v12、PHP 7.4、某些 Python MySQL 驱动)不支持 MySQL 8.0 默认的 caching_sha2_password 认证插件,报错典型是:Client does not support authentication protocol 或 Access denied for user。
临时解法(非长期推荐):
- 登录后执行:
ALTER USER 'appdb'@'203.123.45.67' IDENTIFIED WITH mysql_native_password BY 'StrongPass123!'; - 再查确认:
SELECT user,host,plugin FROM mysql.user WHERE user='appdb';,确保plugin变成了mysql_native_password - 如果必须用新插件,就升级客户端或显式指定驱动参数,例如 Python 的
mysql-connector-python要加auth_plugin='caching_sha2_password'
白名单真正起效的地方不在网络层,而在 MySQL 用户表的 host 字段和云平台安全组的源 IP 规则——这两处写错一个,就等于开了个看不见的洞,或者干脆堵死所有路。











