一、SSL加密通信的重要性
MySQL SSL(Secure Sockets Layer)加密通信可以有效防止:
– 数据窃听:防止中间人攻击窃取敏感数据
– 数据篡改:确保传输数据的完整性
– 身份伪造:验证服务器和客户端身份
| 风险类型 | 无SSL | 有SSL |
|---|---|---|
| 数据窃听 | ❌ 高风险 | ✅ 加密保护 |
| 中间人攻击 | ❌ 易受攻击 | ✅ 证书验证 |
| 合规性 | ❌ 不符合 | ✅ 符合GDPR/等保 |
二、准备工作
2.1 环境要求
- 操作系统:Ubuntu 20.04+/CentOS 7+
- MySQL版本:5.7+(推荐8.0+)
- 权限:root或sudo权限
- OpenSSL:已安装(通常默认安装)
检查OpenSSL版本:
openssl version
# 输出示例:OpenSSL 3.0.2 15 Mar 2022
2.2 检查MySQL是否已启用SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"
如果输出显示 have_ssl = DISABLED 或 have_ssl = YES,继续以下步骤。
三、生成SSL证书和密钥
3.1 创建证书存放目录
sudo mkdir -p /etc/mysql/ssl
sudo chown -R mysql:mysql /etc/mysql/ssl
sudo chmod 700 /etc/mysql/ssl
cd /etc/mysql/ssl
3.2 生成CA证书(证书颁发机构)
# 生成CA私钥
sudo openssl genrsa 2048 > ca-key.pem
# 生成CA证书(有效期10年)
sudo openssl req -new -x509 -nodes -days 3650 \
-key ca-key.pem \
-out ca-cert.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MySQL-CA/CN=MySQL CA"
3.3 生成服务器证书
# 生成服务器私钥
sudo openssl genrsa 2048 > server-key.pem
# 生成证书签名请求(CSR)
sudo openssl req -new -key server-key.pem \
-out server-req.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MySQL-Server/CN=MySQL Server"
# 用CA证书签名服务器证书(有效期10年)
sudo openssl x509 -req -in server-req.pem -days 3650 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \
-out server-cert.pem
3.4 生成客户端证书
# 生成客户端私钥
sudo openssl genrsa 2048 > client-key.pem
# 生成证书签名请求(CSR)
sudo openssl req -new -key client-key.pem \
-out client-req.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MySQL-Client/CN=MySQL Client"
# 用CA证书签名客户端证书(有效期10年)
sudo openssl x509 -req -in client-req.pem -days 3650 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 \
-out client-cert.pem
3.5 设置正确的文件权限
sudo chown mysql:mysql /etc/mysql/ssl/*
sudo chmod 600 /etc/mysql/ssl/*.pem
sudo chmod 644 /etc/mysql/ssl/ca-cert.pem
3.6 验证证书
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
# 输出应显示:server-cert.pem: OK 和 client-cert.pem: OK
四、配置MySQL服务器启用SSL
4.1 编辑MySQL配置文件
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# 或(CentOS/RHEL)
sudo nano /etc/my.cnf
4.2 添加SSL配置
在 [mysqld] 部分添加:
[mysqld]
# SSL配置
ssl-ca=/etc/mysql/ssl/ca-cert.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem
# 强制所有连接使用SSL(可选)
require_secure_transport=ON
4.3 重启MySQL服务
# Ubuntu/Debian
sudo systemctl restart mysql
# CentOS/RHEL
sudo systemctl restart mysqld
4.4 验证SSL已启用
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"
输出应显示:
+---------------+-----------------------------+
| Variable_name | Value |
+---------------+-----------------------------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | /etc/mysql/ssl/ca-cert.pem |
| ssl_cert | /etc/mysql/ssl/server-cert.pem|
| ssl_key | /etc/mysql/ssl/server-key.pem|
+---------------+-----------------------------+
五、配置MySQL用户强制使用SSL
5.1 创建强制SSL的用户
-- 创建新用户并强制使用SSL
CREATE USER 'ssl_user'@'%' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON *.* TO 'ssl_user'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;
5.2 修改现有用户强制SSL
-- 修改现有用户
ALTER USER 'existing_user'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;
5.3 查看用户SSL要求
SELECT user, host, ssl_type FROM mysql.user;
输出示例:
+------------+-----------+----------+
| user | host | ssl_type |
+------------+-----------+----------+
| ssl_user | % | ANY |
| root | localhost | |
+------------+-----------+----------+
六、客户端连接测试
6.1 使用SSL连接(客户端证书)
mysql --ssl-ca=/etc/mysql/ssl/ca-cert.pem \
--ssl-cert=/etc/mysql/ssl/client-cert.pem \
--ssl-key=/etc/mysql/ssl/client-key.pem \
-h 192.168.1.100 -u ssl_user -p
6.2 查看当前连接是否使用SSL
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_version';
输出示例:
+---------------+--------------------+
| Variable_name | Value |
+---------------+--------------------+
| Ssl_cipher | TLS_AES_256_GCM_SHA384 |
| Ssl_version | TLSv1.3 |
+---------------+--------------------+
6.3 强制不使用SSL的连接测试(应失败)
mysql -h 192.168.1.100 -u ssl_user -p --ssl-mode=DISABLED
# 应报错:ERROR 1045 (28000): Access denied for user 'ssl_user'@'...' (using password: YES)
七、应用程序连接配置
7.1 PHP连接示例
<?php
$mysqli = new mysqli();
$mysqli->ssl_set(
'/etc/mysql/ssl/client-key.pem',
'/etc/mysql/ssl/client-cert.pem',
'/etc/mysql/ssl/ca-cert.pem',
NULL,
NULL
);
$mysqli->real_connect(
'192.168.1.100',
'ssl_user',
'StrongPassword123!',
'database_name',
3306,
NULL,
MYSQLI_CLIENT_SSL
);
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
echo "SSL连接成功!\n";
$mysqli->close();
?>
7.2 Python连接示例
import mysql.connector
config = {
'user': 'ssl_user',
'password': 'StrongPassword123!',
'host': '192.168.1.100',
'database': 'database_name',
'ssl_ca': '/etc/mysql/ssl/ca-cert.pem',
'ssl_cert': '/etc/mysql/ssl/client-cert.pem',
'ssl_key': '/etc/mysql/ssl/client-key.pem',
'ssl_verify_cert': True,
}
try:
cnx = mysql.connector.connect(**config)
print("SSL连接成功!")
cnx.close()
except mysql.connector.Error as err:
print(f"错误:{err}")
八、常见问题排查
问题1:MySQL启动失败
排查步骤:
# 查看错误日志
sudo tail -f /var/log/mysql/error.log
# 检查证书权限
ls -la /etc/mysql/ssl/
# 验证证书匹配性
openssl verify -CAfile ca-cert.pem server-cert.pem
问题2:客户端连接报SSL错误
解决方案:
1. 确认客户端证书与服务器CA证书匹配
2. 确认证书未过期:openssl x509 -in client-cert.pem -noout -dates
3. 确认防火墙开放3306端口:sudo ufw allow 3306/tcp
问题3:性能下降
优化建议:
– 使用TLS 1.3(性能优于TLS 1.2)
– 调整MySQL配置:tls_version=TLSv1.3
– 使用连接池减少SSL握手次数
九、安全最佳实践
- 定期更新证书:建议每年更新一次证书
- 证书权限管理:确保证书文件权限为600
- 禁用不安全的SSL版本:
tls_version=TLSv1.2,TLSv1.3 - 监控SSL连接:定期检查
SHOW STATUS LIKE 'Ssl_cipher'; - 备份证书:妥善备份CA证书和私钥
十、总结
配置MySQL SSL加密通信是保护数据库传输安全的必要措施。本文详细介绍了:
1. ✅ SSL证书生成(CA、服务器、客户端)
2. ✅ MySQL服务器SSL配置
3. ✅ 强制用户使用SSL连接
4. ✅ 客户端连接测试
5. ✅ 应用程序SSL连接示例
6. ✅ 常见问题排查
通过以上步骤,您可以在Linux上成功配置MySQL SSL加密通信,有效提升数据库安全性。
注:本文基于MySQL 8.0 + Ubuntu 22.04/CentOS 7编写,其他版本请参考官方文档调整。