Skip to content

MySQL SSL/TLS 配置

SSL/TLS 是保护 MySQL 数据库通信安全的重要技术,它可以加密客户端与服务器之间的通信数据,防止数据被窃听、篡改或伪造。随着网络安全威胁的不断增加,越来越多的企业要求数据库通信必须使用 SSL/TLS 加密。本文将详细介绍 MySQL SSL/TLS 的配置方法、不同版本的特性差异以及生产环境最佳实践。

SSL/TLS 基础

SSL/TLS 的作用

在 MySQL 数据库环境中,SSL/TLS 主要用于:

  • 加密通信数据:加密客户端与服务器之间的所有通信数据,防止数据被窃听
  • 身份验证:验证服务器和客户端的身份,防止中间人攻击
  • 数据完整性:确保通信数据在传输过程中没有被篡改
  • 合规要求:满足企业安全政策和合规要求(如 PCI DSS、GDPR 等)
  • 防止会话劫持:防止攻击者劫持数据库连接会话

MySQL 对 SSL/TLS 的支持

MySQL 从 4.0.0 版本开始支持 SSL/TLS,但不同版本的支持程度和默认配置有所不同:

  • MySQL 5.6:支持 SSL/TLS,但默认不启用
  • MySQL 5.7:支持 SSL/TLS,提供更简单的配置选项
  • MySQL 8.0:从 8.0.11 版本开始,默认启用 SSL/TLS,提供更安全的默认配置

SSL/TLS 相关术语

  • SSL (Secure Sockets Layer):早期的加密协议,已被 TLS 取代
  • TLS (Transport Layer Security):SSL 的继任者,当前广泛使用的加密协议
  • X.509 证书:用于验证服务器和客户端身份的数字证书
  • CA (Certificate Authority):证书颁发机构,负责签发和管理数字证书
  • 自签名证书:由自己签发的证书,适用于测试环境
  • 证书链:从服务器证书到根 CA 证书的完整证书链条

不同版本的 SSL/TLS 特性

MySQL 5.6 SSL/TLS 特性

MySQL 5.6 版本的 SSL/TLS 功能相对基础:

  • 默认不启用:默认不启用 SSL/TLS,需要手动配置
  • 基本加密算法支持:支持 RSA 密钥和基本的加密算法
  • 配置复杂:需要手动生成证书和密钥,配置过程相对复杂
  • 有限的 TLS 版本支持:主要支持 TLS 1.0 和 TLS 1.1
  • 缺乏自动配置工具:没有内置的证书生成和管理工具

MySQL 5.7 SSL/TLS 特性

MySQL 5.7 版本增强了 SSL/TLS 支持:

  • 简化的配置:提供了更简单的 SSL/TLS 配置选项
  • 内置证书生成工具:提供了 mysql_ssl_rsa_setup 工具,用于自动生成证书和密钥
  • 增强的加密算法支持:支持更多的加密算法和密钥长度
  • TLS 1.2 支持:完整支持 TLS 1.2 协议
  • SSL 状态监控:提供了更多的 SSL 状态监控指标

MySQL 8.0 SSL/TLS 特性

MySQL 8.0 版本全面增强了 SSL/TLS 支持:

  • 默认启用:从 8.0.11 版本开始,默认启用 SSL/TLS
  • 更安全的默认配置:默认使用更安全的加密算法和密钥长度
  • TLS 1.3 支持:支持最新的 TLS 1.3 协议,提供更高的性能和安全性
  • 增强的证书管理:提供了更丰富的证书管理功能
  • 加密连接强制:支持强制所有连接使用 SSL/TLS
  • 更详细的 SSL 日志:提供了更详细的 SSL 连接日志

SSL/TLS 证书生成

自签名证书生成

自签名证书适用于测试环境和内部使用:

使用 mysql_ssl_rsa_setup 工具(MySQL 5.7+)

bash
# 生成自签名证书和密钥
mysql_ssl_rsa_setup --datadir=/var/lib/mysql

# 查看生成的证书和密钥
ls -la /var/lib/mysql/*.pem

生成的证书和密钥文件:

  • ca.pem:CA 证书
  • ca-key.pem:CA 私钥
  • server-cert.pem:服务器证书
  • server-key.pem:服务器私钥
  • client-cert.pem:客户端证书
  • client-key.pem:客户端私钥
  • public_key.pem:公钥
  • private_key.pem:私钥(用于 RSA 密钥对)

手动生成自签名证书

使用 OpenSSL 手动生成自签名证书:

bash
# 创建证书目录
mkdir -p /etc/mysql/ssl
cd /etc/mysql/ssl

# 生成 CA 私钥
openssl genrsa 2048 > ca-key.pem

# 生成 CA 证书
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem > ca.pem

# 生成服务器私钥
openssl genrsa 2048 > server-key.pem

# 生成服务器证书请求
openssl req -new -key server-key.pem -out server-req.pem

# 生成服务器证书
openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

# 生成客户端私钥
openssl genrsa 2048 > client-key.pem

# 生成客户端证书请求
openssl req -new -key client-key.pem -out client-req.pem

# 生成客户端证书
openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 02 > client-cert.pem

# 优化私钥权限
chmod 600 ca-key.pem server-key.pem client-key.pem
chown mysql:mysql /etc/mysql/ssl/*

商业证书配置

对于生产环境,建议使用受信任的商业 CA 颁发的证书:

  1. 生成证书请求 (CSR)

    bash
    openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
  2. 提交 CSR 给 CA:将生成的 CSR 文件提交给受信任的 CA,获取签名后的证书

  3. 安装证书:将 CA 颁发的证书和相关文件安装到 MySQL 服务器

  4. 配置 MySQL:配置 MySQL 使用商业 CA 颁发的证书

SSL/TLS 连接配置

服务器端配置

基本 SSL/TLS 配置

在 MySQL 配置文件中添加以下配置:

ini
# MySQL 配置文件 (my.cnf 或 my.ini)
[mysqld]
# 启用 SSL/TLS
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem

# MySQL 8.0+ 配置
# 强制所有连接使用 SSL/TLS
# require_secure_transport=ON

# 指定允许的 TLS 版本
# tls_version=TLSv1.2,TLSv1.3

# 指定允许的加密算法
# ssl_cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

重启 MySQL 服务

bash
# Linux 系统
systemctl restart mysqld
# 或
service mysql restart

# Windows 系统
net stop mysql
net start mysql

验证 SSL/TLS 配置

sql
-- 查看 SSL 配置
SHOW GLOBAL VARIABLES LIKE '%ssl%';

-- 查看 SSL 状态
SHOW STATUS LIKE 'Ssl%';

-- 查看支持的 TLS 版本
SHOW GLOBAL VARIABLES LIKE 'tls_version';

客户端配置

MySQL 客户端 SSL/TLS 连接

bash
# 使用 SSL/TLS 连接到 MySQL 服务器
mysql -u root -p --ssl-ca=/var/lib/mysql/ca.pem --ssl-cert=/var/lib/mysql/client-cert.pem --ssl-key=/var/lib/mysql/client-key.pem

# 或简化版(仅验证服务器证书)
mysql -u root -p --ssl-ca=/var/lib/mysql/ca.pem --ssl-mode=REQUIRED

# MySQL 8.0+ 可以使用以下命令
mysql -u root -p --ssl-mode=REQUIRED

验证客户端 SSL/TLS 连接

sql
-- 查看当前连接是否使用 SSL
STATUS;

-- 或
SHOW SESSION STATUS LIKE 'Ssl_cipher';

应用程序 SSL/TLS 连接

以 PHP 为例,配置应用程序使用 SSL/TLS 连接到 MySQL:

php
// PHP PDO 连接示例
$pdo = new PDO(
    'mysql:host=192.168.1.100;dbname=test;charset=utf8mb4',
    'username',
    'password',
    [
        PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem',
        PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',
        PDO::MYSQL_ATTR_SSL_KEY => '/path/to/client-key.pem',
        PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true
    ]
);

SSL/TLS 连接模式

MySQL 8.0 支持多种 SSL/TLS 连接模式:

模式描述安全性
DISABLED禁用 SSL/TLS最低
PREFERRED优先使用 SSL/TLS,如果服务器不支持则使用非加密连接中等
REQUIRED要求使用 SSL/TLS,否则连接失败
VERIFY_CA要求使用 SSL/TLS,并验证 CA 证书更高
VERIFY_IDENTITY要求使用 SSL/TLS,验证 CA 证书和服务器主机名最高

配置客户端连接模式:

bash
# 使用 VERIFY_IDENTITY 模式
mysql -u root -p --ssl-ca=/var/lib/mysql/ca.pem --ssl-mode=VERIFY_IDENTITY

SSL/TLS 安全加固

配置安全的 TLS 版本

建议仅启用安全的 TLS 版本,禁用过时的 TLS 版本:

ini
[mysqld]
# 仅允许 TLS 1.2 和 TLS 1.3
tls_version=TLSv1.2,TLSv1.3

配置安全的加密算法

建议仅使用安全的加密算法:

ini
[mysqld]
# 配置安全的加密算法
ssl_cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256

强制所有连接使用 SSL/TLS

对于生产环境,建议强制所有连接使用 SSL/TLS:

ini
[mysqld]
# 强制所有连接使用 SSL/TLS
require_secure_transport=ON

配置用户强制使用 SSL/TLS

可以为特定用户配置强制使用 SSL/TLS:

sql
-- 创建用户并要求使用 SSL
CREATE USER 'app_user'@'%' IDENTIFIED BY 'password' REQUIRE SSL;

-- 修改现有用户要求使用 SSL
ALTER USER 'app_user'@'%' REQUIRE SSL;

-- 要求用户使用特定的 SSL 证书
ALTER USER 'app_user'@'%' REQUIRE X509;

-- 要求用户使用特定的客户端证书
ALTER USER 'app_user'@'%' REQUIRE SUBJECT '/C=CN/ST=State/L=City/O=Organization/OU=Department/CN=client';

SSL/TLS 监控与管理

监控 SSL/TLS 连接

sql
-- 查看 SSL 连接状态
SHOW STATUS LIKE 'Ssl%';

-- 查看 SSL 配置
SHOW GLOBAL VARIABLES LIKE '%ssl%';

-- 查看使用 SSL 的连接
SHOW PROCESSLIST;

查看 SSL/TLS 版本和加密算法

sql
-- 查看当前连接的 TLS 版本和加密算法
SELECT @@session.ssl_version, @@session.ssl_cipher;

证书过期监控

定期检查证书过期时间:

bash
# 检查证书过期时间
openssl x509 -in /var/lib/mysql/server-cert.pem -noout -dates

# 检查证书有效期
openssl x509 -in /var/lib/mysql/server-cert.pem -noout -enddate -checkend 86400

SSL/TLS 常见问题排查

无法建立 SSL/TLS 连接

错误信息

ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed

排查步骤

  1. 检查证书文件权限

    bash
    ls -la /var/lib/mysql/*.pem
  2. 检查证书文件路径:确保 MySQL 配置文件中指定的证书路径正确

  3. 检查证书有效性

    bash
    openssl verify -CAfile /var/lib/mysql/ca.pem /var/lib/mysql/server-cert.pem
  4. 检查 TLS 版本兼容性:确保客户端和服务器支持相同的 TLS 版本

  5. 查看 MySQL 错误日志

    bash
    tail -f /var/log/mysqld.log

SSL/TLS 连接性能问题

排查步骤

  1. 检查加密算法:确保使用高效的加密算法(如 AES-GCM)
  2. 检查 TLS 版本:使用 TLS 1.3 可以提高性能
  3. 检查服务器资源:监控服务器 CPU 使用率,SSL/TLS 加密会消耗一定的 CPU 资源
  4. 考虑使用硬件加速:对于高并发场景,考虑使用支持 SSL/TLS 硬件加速的服务器

证书过期问题

排查步骤

  1. 检查证书过期时间

    bash
    openssl x509 -in /var/lib/mysql/server-cert.pem -noout -enddate
  2. 生成新证书:使用 mysql_ssl_rsa_setup 或 OpenSSL 生成新的证书

  3. 更新 MySQL 配置:如果证书路径或文件名发生变化,更新 MySQL 配置

  4. 重启 MySQL 服务

    bash
    systemctl restart mysqld

SSL/TLS 最佳实践

生产环境 SSL/TLS 配置建议

证书管理

  • 使用受信任的 CA:对于生产环境,建议使用受信任的商业 CA 颁发的证书
  • 定期更新证书:定期更新 SSL/TLS 证书,避免证书过期
  • 安全存储私钥:私钥文件应严格权限控制,仅允许 MySQL 进程访问
  • 证书备份:定期备份 SSL/TLS 证书和私钥

加密配置

  • 使用安全的 TLS 版本:仅启用 TLS 1.2 和 TLS 1.3
  • 使用安全的加密算法:使用高效且安全的加密算法
  • 强制使用 SSL/TLS:强制所有连接使用 SSL/TLS
  • 配置用户 SSL 要求:为敏感用户配置强制使用 SSL/TLS

监控与审计

  • 监控 SSL/TLS 连接:定期监控 SSL/TLS 连接状态
  • 监控证书过期:设置证书过期告警
  • 审计 SSL/TLS 配置:定期审计 SSL/TLS 配置,确保符合安全要求
  • 日志记录:启用详细的 SSL/TLS 连接日志

性能优化建议

  • 使用 TLS 1.3:TLS 1.3 提供更高的性能和安全性
  • 使用高效的加密算法:如 AES-GCM 算法
  • 适当的密钥长度:使用 2048 位或 4096 位 RSA 密钥
  • 硬件加速:对于高并发场景,考虑使用支持 SSL/TLS 硬件加速的服务器
  • 连接池:使用连接池减少 SSL/TLS 握手开销

企业级 SSL/TLS 解决方案

集中式证书管理

  • 企业 CA 部署:部署企业级 CA,统一管理所有 MySQL 实例的证书
  • 证书自动更新:实现证书的自动生成和更新
  • 配置管理工具集成:通过 Ansible、Puppet 等配置管理工具统一管理 SSL/TLS 配置

SSL/TLS 策略管理

  • 统一 SSL/TLS 策略:制定企业级的 SSL/TLS 策略,包括加密算法、TLS 版本、密钥长度等
  • 策略自动检查:使用自动化工具检查 SSL/TLS 配置是否符合企业策略
  • 合规检查:确保 SSL/TLS 配置符合合规要求(如 PCI DSS、GDPR 等)

高级加密解决方案

  • 透明数据加密 (TDE):结合 SSL/TLS 使用 TDE 加密静态数据
  • 密钥管理服务 (KMS):使用 KMS 管理 SSL/TLS 证书和密钥
  • 硬件安全模块 (HSM):使用 HSM 存储和管理私钥,提供更高的安全性

总结

SSL/TLS 是保护 MySQL 数据库通信安全的重要技术,合理的 SSL/TLS 配置可以有效防止数据被窃听、篡改或伪造。根据 MySQL 版本的不同,DBA 可以选择不同的 SSL/TLS 配置方案:

  1. MySQL 5.6

    • 手动生成证书和密钥
    • 配置基本的 SSL/TLS 连接
    • 建议仅在必要时使用
  2. MySQL 5.7

    • 使用 mysql_ssl_rsa_setup 工具生成证书
    • 配置 SSL/TLS 连接
    • 考虑为敏感用户启用 SSL/TLS 强制
  3. MySQL 8.0

    • 充分利用默认启用的 SSL/TLS
    • 配置更安全的加密算法和 TLS 版本
    • 强制所有连接使用 SSL/TLS
    • 使用 VERIFY_IDENTITY 连接模式提高安全性

在生产环境中,DBA 应根据企业安全政策和合规要求,配置适当的 SSL/TLS 解决方案,确保数据库通信的安全性。同时,定期监控和审计 SSL/TLS 配置,及时更新证书,确保 SSL/TLS 通信的持续安全。