mysql远程访问需两步:先配置本地允许远程连接(改bind-address为0.0.0.0、创建'%'用户并授权、刷新权限、重启服务),再通过cpolar或花生壳等内网穿透工具将3306端口映射为公网tcp地址,同时开放windows防火墙入站3306端口。

MySQL 本身不支持直接外网暴露,远程办公场景下必须通过内网穿透工具中转流量,否则要么开防火墙放行 3306(极不安全),要么依赖云厂商公网 IP(成本高、权限受限)。核心就两点:MySQL 本地允许远程连 + 穿透工具把 3306 映射出去。
确认 MySQL 已监听所有地址而非仅 localhost
如果 netstat -tlnp | grep mysql 只显示 127.0.0.1:3306,远程连接一定失败。必须改配置让 MySQL 监听真实网卡或全部接口:
- Linux 下编辑
/etc/mysql/mysql.conf.d/mysqld.cnf,找到bind-address行,改成bind-address = 0.0.0.0;Windows 下改my.ini中同名项 - 改完必须重启服务:
sudo systemctl restart mysql(Linux)或在services.msc里重启 MySQL 服务(Windows) - 验证是否生效:执行
ss -tln | grep :3306或netstat -an | findstr :3306,看到*:3306或0.0.0.0:3306才算成功
创建带 % 主机权限的用户并刷新权限
MySQL 默认 root 只允许 'root'@'localhost',远程连接会报错 Access denied for user 'root'@'xxx.xxx.xxx.xxx'。不能直接改 root 的 host,应新建专用用户:
- 登录 MySQL:
mysql -u root -p - 执行建户授权(以用户
devuser、密码P@ssw0rd为例):CREATE USER 'devuser'@'%' IDENTIFIED BY 'P@ssw0rd'; GRANT SELECT, INSERT, UPDATE ON myapp_db.* TO 'devuser'@'%'; FLUSH PRIVILEGES;
- MySQL 8.0+ 用户默认用
caching_sha2_password插件,部分客户端(如旧版 Navicat、某些 JDBC 驱动)不兼容,若连接报错Client does not support authentication protocol,需补一句:ALTER USER 'devuser'@'%' IDENTIFIED WITH mysql_native_password BY 'P@ssw0rd';
用 cpolar 或花生壳映射 3306 端口(TCP 模式)
花生壳免费版限制多(域名随机、带宽低、易掉线),cpolar 更稳定且支持固定 TCP 地址(需升级专业版)。二者操作本质一样,关键点是协议必须选 TCP,不是 HTTP:
- 本地启动 cpolar 后访问
http://localhost:9200,登录账号 - 隧道管理 → 创建隧道:
– 隧道名称:自定义,如mysql-remote
– 协议:选TCP(不是 HTTP/HTTPS)
– 本地地址:127.0.0.1:3306(不要填内网 IP,避免容器或防火墙拦截)
– 域名类型:选“随机 TCP 端口”或“固定 TCP 端口”(后者需付费) - 生成的公网地址形如
tcp://xxxx.cpolar.top:12345,这就是你远程连接时要填的 host 和 port
连接时注意客户端工具的端口和驱动兼容性
很多连接失败不是配置问题,而是工具层细节没对上:
- Navicat / DBeaver / IDEA Database 连接窗口中,“主机”填 cpolar 给的域名(如
xxxx.cpolar.top),“端口”填映射后的外网端口(如12345),不是本地 3306 - Java 应用 JDBC URL 示例:
jdbc:mysql://xxxx.cpolar.top:12345/myapp_db?useSSL=false&serverTimezone=UTC,务必加useSSL=false,否则可能因证书握手失败 - Windows 防火墙默认拦入站 TCP 连接,即使 MySQL 配好了,也得手动放行 3306(控制面板 → Windows Defender 防火墙 → 高级设置 → 入站规则 → 新建规则 → 端口 → TCP 3306)
最常被忽略的是:内网穿透只解决“通路”,MySQL 权限、监听地址、防火墙、客户端驱动这四层只要有一层卡住,就连不上。建议按顺序逐层验证——先 telnet 公网地址+端口看是否通,再试本地连接 MySQL,最后才组合穿透链路。临时调试别用 root,最小权限原则能省去一堆排查时间。











