MySQL 允许远程连接需三步:修改用户 Host 为 % 或指定 IP、配置 bind-address 为 0.0.0.0 或内网 IP、开放防火墙 3306 端口;同时禁用 root 远程登录、启用 SSL 加密、建议使用 SSH 隧道提升安全性。

MySQL 默认禁止远程连接,要允许远程登录,必须同时修改用户权限和服务器配置,否则即使开了 防火墙 端口 也无法访问。
修改 MySQL 用户的主机权限
MySQL 用户账号由“用户名 @主机名”组成,默认创建的用户通常只允许本地(localhost)登录。要支持远程访问,需将主机部分改为具体 IP 或通配符 %。
- 登录 MySQL(需有 root 权限):mysql -u root -p
- 查看当前用户及允许访问的主机:SELECT User, Host FROM mysql.user;
- 若已有用户(如 appuser),但 Host 是 localhost,可直接更新:UPDATE mysql.user SET Host=’%’ WHERE User=’appuser’ AND Host=’localhost’;
- 更推荐新建专用远程用户(更安全):CREATE USER ‘appuser’@’192.168.1.%’ IDENTIFIED BY ‘StrongPass123!’;(限制在内网段)或 CREATE USER ‘appuser’@’%’ IDENTIFIED BY ‘StrongPass123!’;(全网,慎用)
- 赋予必要权限(避免直接 GRANT ALL):GRANT SELECT, INSERT, UPDATE ON mydb.* TO ‘appuser’@’192.168.1.%’;
- 刷新权限:FLUSH PRIVILEGES;
检查并修改 MySQL 绑定地址
MySQL 服务默认只监听 127.0.0.1(本地环回),需改为监听实际网卡 IP 或 0.0.0.0(所有接口)才能接收远程请求。
- 编辑 配置文件(路径因系统而异):
• Ubuntu/Debian:/etc/mysql/mysql.conf.d/mysqld.cnf
• CentOS/RHEL:/etc/my.cnf 或 /etc/my.cnf.d/mysql-server.cnf - 查找 bind-address 行,将其改为:
bind-address = 0.0.0.0(允许所有 IPv4 地址)
或更安全地指定内网 IP:bind-address = 192.168.1.100 - 保存后重启 MySQL:sudo systemctl restart mysql(或 mysqld)
- 验证监听状态:sudo ss -tlnp | grep :3306,应看到 0.0.0.0:3306 或对应 IP
开放防火墙与网络层访问控制
即使 MySQL 配置正确,若系统防火墙或云平台安全组拦截 3306 端口,仍无法连接。
- Ubuntu(UFW):sudo ufw allow from 192.168.1.50 to any port 3306(仅允特定客户端)
- CentOS(firewalld):sudo firewall-cmd –permanent –add-rich-rule=’rule family=”ipv4″ source address=”192.168.1.50″ port port=”3306″ protocol=”tcp” accept’,再 firewall-cmd –reload
- 阿里云 / 腾讯 云等:进入「安全组」规则,添加入方向 TCP:3306,源 IP 设为具体 IP 或最小化 CIDR(如 192.168.1.0/24)
- 生产环境强烈建议禁用公网 3306 开放,改用跳板机、SSH 隧道或 VPC 内网访问
加固远程访问安全性
开放远程访问会扩大攻击面,必须叠加基础防护措施。
- 禁用 root 远程登录:UPDATE mysql.user SET Host=’localhost’ WHERE User=’root’; FLUSH PRIVILEGES;
- 强制使用强密码(长度 ≥12,含大小写字母 + 数字 + 符号),并定期轮换
- 启用 MySQL 的 require_secure_transport(MySQL 5.7+):
在 my.cnf 中添加 require_secure_transport = ON,并配置 SSL 证书,强制加密连接 - 考虑用 SSH 隧道替代明文远程连接:
ssh -L 3307:127.0.0.1:3306 user@mysql-server-ip,然后本地连 127.0.0.1:3307 - 定期审计用户权限:SELECT User, Host, authentication_string FROM mysql.user;,删除闲置账户