OpenEuler24.03 MySQL SSL 配置指南
一、SSL加密的意义
MySQL通过SSL证书实现以下安全保障:
- 身份验证:验证服务端/客户端身份,防止中间人攻击
- 数据加密:加密传输过程中的数据,防止窃听和篡改
- 合规要求:满足等保、GDPR等法规对数据安全的要求
二、前提条件
1. 环境检查
bash
# 检查MySQL版本(需要5.7+,推荐8.0+)
mysql -V
# 检查OpenSSL版本(需要1.1.1+)
openssl version
2. MySQL版本支持
- MySQL 5.7及以上默认支持SSL
- MySQL 8.0+内置自动证书生成工具(推荐使用)
三、证书生成方案
方案一:重启mysqld进程自动生成
apl
systemctl restart mysqld
[root@localhost mysql]# ls /var/lib/mysql
auto.cnf binlog.000006 binlog.index client-key.pem ib_buffer_pool '#innodb_temp' mysql.sock.lock private_key.pem sys
binlog.000003 binlog.000007 ca-key.pem db1 ibdata1 mysql mysqlx.sock public_key.pem undo_001
binlog.000004 binlog.000008 ca.pem '#ib_16384_0.dblwr' ibtmp1 mysql.ibd mysqlx.sock.lock server-cert.pem undo_002
binlog.000005 binlog.000009 client-cert.pem '#ib_16384_1.dblwr' '#innodb_redo' mysql.sock performance_schema server-key.pem xtrabackup_info
方案二:MySQL 8.0+内置工具自动生成(推荐)
bash
# 1. 进入MySQL数据目录
cd /var/lib/mysql
chown mysql:mysql .
# 2. 生成SSL证书
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --uid=mysql
# 3. 查看生成的证书文件
ls -l /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 # RSA公钥(用于无密码认证)
private_key.pem # RSA私钥
方案三:手动生成证书(通用)
bash
# 1. 创建证书目录
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. 生成服务端证书
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. 生成客户端证书
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. 调整权限
chmod 600 *.pem
chown mysql:mysql *.pem
四、服务端配置
1. 修改MySQL配置文件
bash
# 编辑MySQL配置文件
vi /etc/my.cnf
添加以下配置:
ini
[mysqld]
# 启用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
# 可选:设置加密套件(仅允许安全的加密算法)
tls_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
2. 重启MySQL服务
bash
systemctl restart mysqld
systemctl status mysqld
3. 验证SSL启用状态
bash
# 登录MySQL
mysql -u root -p
# 查看SSL状态
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 |
+---------------+---------------------------+
五、客户端配置
方式一:命令行连接
bash
# 基本SSL连接
mysql -h 192.168.1.100 -u root -p --ssl-mode=REQUIRED
# 严格验证证书(生产环境建议)
mysql -h 192.168.1.100 -u root -p \
--ssl-mode=VERIFY_CA \
--ssl-ca=/var/lib/mysql/ca.pem \
--ssl-cert=/var/lib/mysql/client-cert.pem \
--ssl-key=/var/lib/mysql/client-key.pem
方式二:配置文件持久化
bash
##从mysql服务端拷贝对应的ca及client文件到客户端
scp ca.pem 192.168.100.166:/opt
scp client-cert.pem 192.168.100.166:/opt
scp client-key.pem 192.168.100.166:/opt
# 编辑客户端配置文件
vi ~/.my.cnf
添加以下配置:
ini
[client]
host=服务端ip
port=3306
user=root
password=root密码
ssl-mode=VERIFY_CA
ssl-ca=/opt/ca.pem
ssl-cert=/opt/client-cert.pem
ssl-key=/opt/client-key.pem
方式三:配置用户强制SSL
sql
-- 授权用户仅能通过SSL连接
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password' REQUIRE SSL;
-- 更严格的要求(验证客户端证书)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password' REQUIRE X509;
FLUSH PRIVILEGES;
-- 查看用户SSL权限
SELECT user, host, ssl_type FROM mysql.user WHERE user='root';
六、验证SSL连接
1. 查看当前连接的SSL状态
sql
-- 查看SSL加密套件
SHOW STATUS LIKE 'Ssl_cipher';
-- 查看完整连接状态
STATUS;
预期输出:
+---------------+-----------------------------+
| Variable_name | Value |
+---------------+-----------------------------+
| Ssl_cipher | TLS_AES_256_GCM_SHA384 |
+---------------+-----------------------------+
2. 网络层面验证
bash
# 使用tcpdump抓包验证
tcpdump -i ens160 port 3306 -nn -A | grep -i "select"
未加密 :能看到明文SQL语句
已加密:流量为乱码,无明文SQL
七、生产环境安全加固建议
1. 证书管理
- 定期轮换证书:建议每年轮换一次证书
- 证书存储安全:证书文件权限设为600,仅允许mysql用户读取
- 客户端证书分发:通过安全通道分发客户端证书,避免泄露
2. 协议与加密算法
- 禁用老旧协议:仅允许TLSv1.2+,禁用TLSv1.0/TLSv1.1
- 使用强加密套件:优先使用AES-256、ChaCha20等现代加密算法
3. 访问控制
- 强制SSL连接 :启用
require_secure_transport=ON - 客户端证书验证 :对敏感用户使用
REQUIRE X509强制客户端证书验证 - IP白名单:结合iptables/firewalld限制MySQL端口访问
4. 监控与审计
- 日志监控:定期查看MySQL错误日志,关注SSL相关报错
- 连接审计:启用MySQL审计日志,记录所有SSL连接
- 性能监控:监控SSL连接对CPU和网络的影响
八、常见问题排查
问题1:MySQL启动失败,日志报"SSL error: Unable to get private key"
原因 :服务端私钥文件权限错误或带密码
解决:
bash
chmod 600 /var/lib/mysql/server-key.pem
chown mysql:mysql /var/lib/mysql/server-key.pem
问题2:客户端连接报错"SSL connection error: protocol version mismatch"
原因 :服务端和客户端支持的TLS版本不一致
解决:
ini
# 在my.cnf中添加
tls_version=TLSv1.2,TLSv1.3
问题3:客户端连接报错"X509_V_ERR_IP_ADDRESS_MISMATCH"
原因 :证书中的IP地址与实际访问IP不匹配
解决:
bash
# 重新生成证书时,确保Common Name或subjectAltName包含正确的IP
问题4:启用SSL后性能下降
原因 :SSL加密需要额外的CPU开销
解决:
- 启用硬件加速(如果CPU支持)
- 升级到更高版本的OpenSSL(推荐1.1.1+)
- 对非敏感业务可选择不强制SSL
九、SSL证书备份与恢复
证书备份
bash
# 备份所有证书文件
cp /var/lib/mysql/*.pem /data/backup/mysql/ssl/
tar -czf /data/backup/mysql/ssl_backup_$(date +%Y%m%d).tar.gz /data/backup/mysql/ssl/
恢复证书
bash
# 恢复证书到指定目录
tar -xzf /data/backup/mysql/ssl_backup_20260331.tar.gz -C /
chown mysql:mysql /var/lib/mysql/*.pem
chmod 600 /var/lib/mysql/*.pem
十、与现有备份脚本集成
修改备份脚本支持SSL
在mysql_xtrabackup_auto.sh中添加SSL参数:
bash
# 备份命令中添加SSL参数
xtrabackup --defaults-file=${DB_CNF} \
--backup \
--target-dir=${FULL_BACKUP_PATH} \
--compress \
--ssl-ca=/var/lib/mysql/ca.pem \
--ssl-cert=/var/lib/mysql/client-cert.pem \
--ssl-key=/var/lib/mysql/client-key.pem
修改恢复脚本支持SSL
在mysql_xtrabackup_restore_fixed.sh中添加SSL参数:
bash
# 恢复命令中添加SSL参数
xtrabackup --defaults-file=${DB_CNF} \
--prepare \
--target-dir=${FULL_BACKUP_DIR} \
--ssl-ca=/var/lib/mysql/ca.pem \
--ssl-cert=/var/lib/mysql/client-cert.pem \
--ssl-key=/var/lib/mysql/client-key.pem
附录:SSL相关参数说明
| 参数 | 说明 | 示例 |
|---|---|---|
| ssl | 是否启用SSL | ssl=ON |
| ssl_ca | CA根证书路径 | ssl_ca=/var/lib/mysql/ca.pem |
| ssl_cert | 服务端证书路径 | ssl_cert=/var/lib/mysql/server-cert.pem |
| ssl_key | 服务端私钥路径 | ssl_key=/var/lib/mysql/server-key.pem |
| require_secure_transport | 强制所有连接使用SSL | require_secure_transport=ON |
| tls_version | 允许的TLS协议版本 | tls_version=TLSv1.2,TLSv1.3 |
| tls_ciphersuites | 允许的加密套件 | tls_ciphersuites=TLS_AES_256_GCM_SHA384 |
| ssl-mode参数 | 说明 |
|---|---|
| DISABLED | 禁用SSL |
| PREFERRED | 优先尝试SSL,失败则降级为非SSL |
| REQUIRED | 必须使用SSL,否则拒绝连接 |
| VERIFY_CA | 验证服务端证书的CA有效性 |
| VERIFY_IDENTITY | 验证服务端证书的主机名/IP匹配 |