为MySQL配置SSL加密访问

要为MySQL配置SSL加密访问,核心目标是让客户端与MySQL服务端之间的网络传输数据被SSL/TLS加密,防止数据在传输过程中被窃听、篡改或伪造。以下是完整的配置步骤(涵盖自建证书、服务端配置、客户端验证),分为「测试环境(自建自签名证书)」和「生产环境(CA签发证书)」两种场景。

这里着重讲解自建方案,个人感觉自建方案可操作性强,CA签发证书一年需要更新一次,对于数据库来讲谁也受不了。

一、前提说明

  1. MySQL版本要求:5.7及以上默认支持SSL,8.0+内置简易证书生成工具(推荐使用);

  2. 核心逻辑:MySQL通过SSL证书完成服务端/客户端身份验证,同时加密传输数据;

  3. 证书类型:

    • 自签名证书:适合测试/内网环境,无需CA认证,但客户端需信任该证书;

    • CA签发证书:适合生产环境,安全性更高,需向可信CA申请证书。


二、步骤1:生成SSL证书(自建自签名,测试环境)

方式1:MySQL内置工具自动生成(推荐,8.0+)

MySQL 8.0+提供mysql_ssl_rsa_setup工具,可一键生成自签名SSL证书:

复制代码
# 1. 进入MySQL数据目录(需确认目录权限,通常为/var/lib/mysql/)
cd /var/lib/mysql
chown mysql:mysql .  # 确保mysql用户有读写权限

# 2. 生成SSL证书(--datadir指定证书存放目录)
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --uid=mysql

# 3. 查看生成的证书文件(关键文件如下)
ls -l /var/lib/mysql/*.pem
# 核心文件说明:
# ca.pem          → CA根证书(客户端需信任)
# server-cert.pem → 服务端证书
# server-key.pem  → 服务端私钥
# client-cert.pem → 客户端证书
# client-key.pem  → 客户端私钥

方式2:手动生成(适配5.7+/8.0,通用)

mysql_ssl_rsa_setup不可用,用openssl手动生成:

复制代码
# 1. 创建证书目录(建议与MySQL数据目录分离)
mkdir -p /etc/mysql/ssl
chown mysql:mysql /etc/mysql/ssl
cd /etc/mysql/ssl

# 2. 生成CA根证书(有效期10年)
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem > ca.pem

# 3. 生成服务端证书(填写信息时,Common Name需为MySQL服务端IP/域名)
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

# 4. 生成客户端证书(Common Name可任意,建议区分服务端)
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 02 > client-cert.pem

# 5. 调整权限(仅mysql用户可读写,防止私钥泄露)
chmod 600 *.pem
chown mysql:mysql *.pem

三、步骤2:配置MySQL服务端启用SSL

1. 修改MySQL配置文件

编辑MySQL配置文件(Linux:/etc/my.cnf//etc/mysql/my.cnf;Windows:my.ini),添加以下配置:

复制代码
[mysqld]
# 启用SSL(强制服务端使用SSL)
ssl=ON
# 指定证书路径(根据实际生成路径修改)
ssl-ca=/var/lib/mysql/ca.pem          # CA根证书
ssl-cert=/var/lib/mysql/server-cert.pem  # 服务端证书
ssl-key=/var/lib/mysql/server-key.pem    # 服务端私钥

# 可选:强制所有客户端连接必须使用SSL(生产环境建议开启)
# require_secure_transport=ON

# 可选:指定SSL协议版本(避免老旧协议,生产环境建议)
tls_version=TLSv1.2,TLSv1.3

2. 重启MySQL服务

复制代码
# Linux(Systemd)
systemctl restart mysqld

# Linux(SysV)
service mysqld restart

# Windows
net stop mysql && net start mysql

3. 验证服务端SSL是否启用

登录MySQL服务端,执行以下命令:

复制代码
-- 查看SSL状态(Ssl_enabled为YES表示启用成功)
SHOW VARIABLES LIKE '%ssl%';
/* 预期输出:
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| have_ssl      | YES                       |
| ssl_ca        | /var/lib/mysql/ca.pem     |
| ssl_cert      | /var/lib/mysql/server-cert.pem |
| ssl_key       | /var/lib/mysql/server-key.pem   |
+---------------+---------------------------+
*/

四、步骤3:配置客户端SSL连接

场景1:客户端连接时手动指定SSL(非强制)

客户端连接MySQL时,通过参数指定SSL证书,实现加密连接:

复制代码
# MySQL客户端命令行连接(替换为你的IP/端口/用户名)
mysql -h 192.168.1.100 -P 3306 -u root -p \
  --ssl-mode=REQUIRED \
  --ssl-ca=/var/lib/mysql/ca.pem \
  --ssl-cert=/var/lib/mysql/client-cert.pem \
  --ssl-key=/var/lib/mysql/client-key.pem

参数说明:

  • --ssl-mode=REQUIRED:强制使用SSL连接,无SSL则拒绝(可选值:DISABLED/REQUIRED/VERIFY_CA/VERIFY_IDENTITY);

  • --ssl-ca:指定CA根证书(验证服务端证书合法性);

  • --ssl-cert/--ssl-key:客户端证书/私钥(服务端验证客户端身份时需用)。

场景2:授权用户必须使用SSL连接(生产环境)

为MySQL用户配置"仅允许SSL加密连接",防止明文连接:

复制代码
-- 授权root用户仅能通过SSL从任意主机访问(替换为你的用户/IP)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的密码' REQUIRE SSL;

-- 刷新权限
FLUSH PRIVILEGES;

-- 查看用户的SSL权限(Ssl_type为SSL表示强制)
SELECT user, host, ssl_type FROM mysql.user WHERE user='root';

场景3:客户端配置文件持久化SSL(无需每次输参数)

编辑客户端~/.my.cnf(Linux)或%APPDATA%\MySQL\.my.cnf(Windows):

复制代码
[client]
host=192.168.1.100
port=3306
user=root
password=你的密码
ssl-mode=REQUIRED
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/client-cert.pem
ssl-key=/var/lib/mysql/client-key.pem

之后直接执行mysql即可自动使用SSL连接。


五、步骤4:验证SSL加密是否生效

1. 客户端验证连接状态

登录MySQL后,执行以下命令:

复制代码
-- 查看当前连接的SSL状态(Ssl_cipher非空表示加密生效)
SHOW STATUS LIKE 'Ssl_cipher';
/* 预期输出:
+---------------+-----------------------------+
| Variable_name | Value                       |
+---------------+-----------------------------+
| Ssl_cipher    | TLS_AES_256_GCM_SHA384      |
+---------------+-----------------------------+
*/

2. 网络层面验证(可选)

tcpdump/wireshark抓包,查看MySQL端口(3306)的流量:

  • 未加密:能看到明文的SQL语句(如SELECT * FROM user);

  • 已加密:流量为乱码,无明文SQL。


六、关键注意事项

  1. 生产环境建议

    • 不要使用自签名证书,改用Let's Encrypt等可信CA签发的证书;

    • 启用require_secure_transport=ON,强制所有连接使用SSL;

    • 限制SSL协议版本为TLSv1.2+,禁用TLSv1.0/TLSv1.1(老旧协议有安全漏洞)。

    1. 权限安全
    • 证书文件(尤其是私钥.pem)必须仅对mysql用户可读写(权限600),防止泄露;

    • 客户端证书不要随意外传,仅分发给可信客户端。

    1. 性能影响
    • SSL加密会增加少量CPU开销(约5%-10%),高并发场景可通过硬件加速优化;

    • 若内网环境已做网络隔离,可仅对跨公网的连接启用SSL。

    1. 常见问题
    • 连接失败提示SSL connection error:检查证书路径/权限、MySQL服务端SSL是否启用;

    • 客户端验证失败:确保CA证书一致,服务端/客户端证书的Common Name匹配;

    • MySQL 5.7以下:需手动编译启用SSL,建议升级到5.7+。

相关推荐
NGSI vimp12 分钟前
MySQL|MySQL 中 `DATE_FORMAT()` 函数的使用
数据库·mysql
秋914 分钟前
MySQL8.0.46 与 MySQL8.4.9:跨越代际的深度差异解析与升级全指南
mysql
HAWK eoni21 分钟前
Mysql 驱动程序
数据库·mysql
xxjj998a37 分钟前
Laravel4.x核心特性全解析
android·mysql·laravel
何中应43 分钟前
CentOS 7安装、卸载MySQL数据库(二)
数据库·mysql·centos
梁萌1 小时前
mysql使用事件做日志表数据转移
数据库·mysql
lThE ANDE1 小时前
MySQL中的TRUNCATE TABLE命令
数据库·mysql
STER labo2 小时前
mysql配置环境变量——(‘mysql‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件解决办法)
数据库·mysql·adb
dreamZhanglx2 小时前
MySQL进阶
数据库·mysql
xmjd msup2 小时前
MySQL 函数
数据库·mysql