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加密

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


有问题评论区聊。

相关推荐
0和1的舞者1 天前
基于Spring的论坛系统-前置知识
java·后端·spring·系统·开发·知识
invicinble1 天前
对于springboot
java·spring boot·后端
码界奇点1 天前
基于Spring Boot与Vue的校园后台管理系统设计与实现
vue.js·spring boot·后端·毕业设计·源代码管理
爱编程的小庄1 天前
Rust 发行版本及工具介绍
开发语言·后端·rust
Apifox.1 天前
测试用例越堆越多?用 Apifox 测试套件让自动化回归更易维护
运维·前端·后端·测试工具·单元测试·自动化·测试用例
sunnyday04261 天前
Nginx与Spring Cloud Gateway QPS统计全攻略
java·spring boot·后端·nginx
康王有点困1 天前
Link入门
后端·flink
海南java第二人1 天前
Spring Boot全局异常处理终极指南:打造优雅的API错误响应体系
java·spring boot·后端
小楼v1 天前
消息队列的核心概念与应用(RabbitMQ快速入门)
java·后端·消息队列·rabbitmq·死信队列·交换机·安装步骤
小北方城市网1 天前
接口性能优化实战:从秒级到毫秒级
java·spring boot·redis·后端·python·性能优化