MySQL远程连接配置与安全实战

本地开发连公司数据库,在家连公司测试环境,远程运维生产库...

MySQL远程连接是刚需,但配置不当就是安全隐患。这篇整理一下远程连接的正确姿势。


为什么连不上?

先说最常见的问题:MySQL装好了,远程连不上。

原因通常就这几个:

1. MySQL没有监听外网

bash 复制代码
# 查看MySQL监听地址
netstat -tlnp | grep 3306

# 如果显示 127.0.0.1:3306,说明只监听本地
# 需要改成 0.0.0.0:3306 或具体IP

修改配置:

ini 复制代码
# /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf
[mysqld]
bind-address = 0.0.0.0

重启MySQL:

bash 复制代码
systemctl restart mysql

2. 用户没有远程权限

sql 复制代码
-- 查看用户权限
SELECT user, host FROM mysql.user;

-- 如果host是localhost,就只能本地连
-- user: root, host: localhost  ← 只能本地
-- user: root, host: %          ← 可以任意IP连接

创建远程用户或修改权限:

sql 复制代码
-- 方式1:创建新用户
CREATE USER 'dev'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_db.* TO 'dev'@'%';
FLUSH PRIVILEGES;

-- 方式2:修改现有用户(不推荐直接改root)
-- MySQL 8.0
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';

3. 防火墙拦截

bash 复制代码
# 查看防火墙状态
ufw status
# 或
firewall-cmd --list-all

# 开放3306端口
ufw allow 3306
# 或
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload

4. 云服务器安全组

如果是云服务器,还要在控制台开安全组:

makefile 复制代码
入站规则:
协议: TCP
端口: 3306
来源: 0.0.0.0/0 (或指定IP)

远程连接的几种方式

1. 直接连接(不推荐)

bash 复制代码
mysql -h 公网IP -P 3306 -u dev -p

问题:

  • 3306端口暴露在公网,容易被扫描攻击
  • 密码在网络上明文传输(除非用SSL)
  • 安全隐患很大

2. SSH隧道(推荐)

通过SSH建立加密隧道,MySQL流量走SSH通道:

bash 复制代码
# 本地执行
ssh -L 3307:localhost:3306 user@server_ip

# 然后连接本地3307端口
mysql -h 127.0.0.1 -P 3307 -u dev -p

或者用Navicat/DataGrip等工具的SSH隧道功能:

makefile 复制代码
SSH主机: server_ip
SSH用户: user
SSH密钥: ~/.ssh/id_rsa

MySQL主机: localhost (注意是localhost,不是server_ip)
MySQL端口: 3306

优点:

  • MySQL端口不用暴露公网
  • 流量加密
  • 可以用SSH密钥认证

3. VPN/组网方案

如果经常需要连接,每次建SSH隧道挺麻烦的。

更好的方式是组建虚拟局域网,让你的电脑和服务器像在同一个内网:

scss 复制代码
你的电脑(192.168.100.2) ←→ 虚拟网络 ←→ 服务器(192.168.100.1)
                                        └── MySQL(192.168.100.1:3306)

这样直接连内网IP就行:

bash 复制代码
mysql -h 192.168.100.1 -P 3306 -u dev -p

我自己用的是星空组网,配置比较简单,装个客户端就能用。特别是公司有多台服务器的情况,组好网后运维方便很多,不用每台机器都配SSH隧道。


安全配置

远程连接开了,安全措施得跟上。

1. 限制访问IP

sql 复制代码
-- 只允许特定IP连接
CREATE USER 'dev'@'192.168.1.%' IDENTIFIED BY 'password';
-- 只允许192.168.1.x网段

-- 或者更精确
CREATE USER 'dev'@'192.168.1.100' IDENTIFIED BY 'password';

2. 最小权限原则

sql 复制代码
-- 别给ALL PRIVILEGES,按需授权
GRANT SELECT, INSERT, UPDATE ON app_db.* TO 'app_user'@'%';

-- 开发环境可以宽松点
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON dev_db.* TO 'dev'@'%';

-- 只读用户
GRANT SELECT ON prod_db.* TO 'readonly'@'%';

3. 强密码

sql 复制代码
-- MySQL 8.0 密码策略
SHOW VARIABLES LIKE 'validate_password%';

-- 设置密码策略
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length = 12;

4. 开启SSL

ini 复制代码
# my.cnf
[mysqld]
require_secure_transport = ON
ssl-ca = /path/to/ca.pem
ssl-cert = /path/to/server-cert.pem
ssl-key = /path/to/server-key.pem

连接时指定SSL:

bash 复制代码
mysql -h server_ip -u dev -p --ssl-mode=REQUIRED

5. 修改默认端口

ini 复制代码
# my.cnf
[mysqld]
port = 13306

不能防住专业攻击,但能挡住大部分自动化扫描。

6. 禁用危险功能

ini 复制代码
# my.cnf
[mysqld]
local-infile = 0           # 禁用LOAD DATA LOCAL
skip-symbolic-links = 1    # 禁用符号链接

连接工具推荐

命令行

bash 复制代码
# 基础连接
mysql -h host -P port -u user -p

# 指定数据库
mysql -h host -u user -p database_name

# 执行SQL文件
mysql -h host -u user -p database_name < script.sql

GUI工具

Navicat:功能全,收费

DBeaver:免费开源,支持多种数据库

DataGrip:JetBrains出品,IDE级别体验

MySQL Workbench:官方工具,免费

配置SSH隧道(以DBeaver为例):

markdown 复制代码
1. 新建连接 → MySQL
2. SSH标签页:
   - 勾选 Use SSH Tunnel
   - Host: 服务器公网IP
   - Port: 22
   - User: SSH用户名
   - Authentication: Public Key
   - Private key: 选择私钥文件
3. Main标签页:
   - Host: localhost
   - Port: 3306
   - Database: 数据库名
   - Username: MySQL用户名

常见问题

1. Host 'xxx' is not allowed to connect

sql 复制代码
-- 查看用户的host设置
SELECT user, host FROM mysql.user WHERE user = 'your_user';

-- 修改或新增
CREATE USER 'your_user'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'your_user'@'%';
FLUSH PRIVILEGES;

2. Authentication plugin 'caching_sha2_password' cannot be loaded

MySQL 8.0默认用新的认证方式,老客户端可能不支持:

sql 复制代码
-- 改成旧的认证方式
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

或者升级客户端。

3. Lost connection to MySQL server

可能原因:

  • 网络不稳定
  • 查询执行时间过长
  • 连接超时
ini 复制代码
# my.cnf 调整超时
[mysqld]
wait_timeout = 28800
interactive_timeout = 28800
net_read_timeout = 60
net_write_timeout = 60

4. Too many connections

sql 复制代码
-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看最大连接数
SHOW VARIABLES LIKE 'max_connections';

-- 临时调大
SET GLOBAL max_connections = 500;

永久修改要改my.cnf。


总结

MySQL远程连接的安全姿势:

  1. 不要把3306直接暴露公网
  2. 用SSH隧道组网方案连接
  3. 限制用户访问IP
  4. 最小权限原则
  5. 开启SSL加密

记住:方便和安全往往是矛盾的。图方便开放所有权限,迟早出事。


有问题评论区聊。

相关推荐
小码编匠2 小时前
工业视觉 C# + OpenCvSharp 的模板匹配实战
后端·c#·.net
To Be Clean Coder3 小时前
【Spring源码】getBean源码实战(二)
java·后端·spring
程序员爱钓鱼3 小时前
Node.js 编程实战:RESTful API 设计
前端·后端·node.js
程序员爱钓鱼3 小时前
Node.js 编程实战:GraphQL 简介与实战
前端·后端·node.js
降临-max3 小时前
JavaWeb企业级开发---MySQL
java·开发语言·数据库·笔记·后端·mysql
思成Codes4 小时前
Golang并发编程——CSP模型
开发语言·后端·golang
郑泰科技4 小时前
SpringBoot项目实践:之前war部署到服务器好用,重新打包部署到服务器报404
服务器·spring boot·后端
IT_陈寒4 小时前
Vite 5 实战:7个鲜为人知的配置技巧让构建速度提升200%
前端·人工智能·后端
Codebee4 小时前
实战|Ooder 钩子机制全解析:AI 协同开发与权限框架集成实战
人工智能·后端