必须同步配置云安全组、系统防火墙、mysql绑定地址和用户权限四层:宝塔放行3306仅是第一步;需在云平台安全组添加tcp 3306入向规则;用firewall-cmd或ufw放行端口;修改my.cnf中bind-address为0.0.0.0并重启mysql;执行grant授权及flush privileges;mysql 8+需指定mysql_native_password插件。

宝塔面板里放行3306端口只是第一步,不是全部
只在宝塔「安全」页面添加3306端口规则,大概率连不上。宝塔自带防火墙只是其中一环,系统级防火墙(firewalld 或 ufw)和云厂商安全组是另外两道独立关卡。
实操建议:
- 先确认宝塔防火墙已启用且 3306 规则存在:进「安全」→ 查看「系统防火墙」状态是否为「运行中」,规则列表里有
3306且协议为TCP - 再查系统防火墙:
sudo firewall-cmd --state(CentOS/Rocky)或sudo ufw status(Ubuntu/Debian),若启用,必须额外执行:sudo firewall-cmd --add-port=3306/tcp --permanent && sudo firewall-cmd --reload或sudo ufw allow 3306 - 云服务器(阿里云/腾讯云等)必须去控制台「安全组」手动加一条入方向规则:协议选
TCP,端口填3306/3306,授权对象填你客户端的公网 IP(别填0.0.0.0/0,尤其生产环境)
改完 phpMyAdmin 里的 host 字段 ≠ 远程权限生效
在宝塔数据库页点「管理」进 phpMyAdmin,把用户「主机」从 localhost 改成 %,这只是改了界面显示值,不触发 MySQL 权限重载——实际权限没变。
真正起效的操作必须走命令行:
- 登录 MySQL:
mysql -u root -p - 执行授权(以用户
myuser为例):GRANT ALL ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypass'; - 强制刷新权限缓存:
FLUSH PRIVILEGES;—— 这一步漏掉,前面全白干 - 验证是否生效:
SELECT user, host FROM mysql.user WHERE user = 'myuser';,结果中host列必须是%,不是localhost
bind-address = 127.0.0.1 是静默拦截器,根本收不到请求
即使权限开了、防火墙通了,MySQL 进程如果只绑在 127.0.0.1,它压根不会接收任何来自外部的 TCP 包。这不是报错,是直接丢弃,所以你会看到 Connection refused。
检查并修改配置文件:
- 配置路径通常是
/www/server/mysql/etc/my.cnf或/etc/my.cnf - 找到
bind-address行,改成:bind-address = 0.0.0.0(监听所有 IPv4 地址)或注释掉整行(# 开头) - 确认没有
skip-networking这一行,有就删掉或注释 - 改完必须重启服务:
systemctl restart mysqld(CentOS)或systemctl restart mysql(Ubuntu/Debian) - 验证监听状态:
netstat -tlnp | grep :3306,看到0.0.0.0:3306才算成功
MySQL 8+ 的 caching_sha2_password 插件会导致“密码正确却连不上”
MySQL 8.0 默认用 caching_sha2_password 认证插件,但旧版 Navicat、某些 PHP 版本、Python 的 pymysql 默认不支持,表现就是 Access denied,哪怕账号密码完全正确。
解决方法是显式指定兼容插件:
- 创建用户时直接指定:
CREATE USER 'myuser'@'%' IDENTIFIED WITH mysql_native_password BY 'mypass'; - 或对已有用户修改:
ALTER USER 'myuser'@'%' IDENTIFIED WITH mysql_native_password BY 'mypass'; - 执行后仍需
FLUSH PRIVILEGES; - 如果用的是
root用户远程连接,注意它默认是'root'@'localhost',得先DROP USER 'root'@'localhost';再重建@'%'版本,否则新权限不覆盖旧记录
真正的难点不在步骤多,而在于四层隔离:云安全组 → 系统防火墙 → MySQL 绑定地址 → 用户 host 权限。任意一层卡住,现象都是“连不上”,但原因完全不同。验证时别跳步,telnet your-db-ip 3306 能通,才说明前两层没问题;netstat 看到监听,才说明第三层过了;最后才是 SQL 权限和认证插件的事。











