启用 SSL 以实现安全连接
在这一步中,我们将为你的 MySQL 服务器启用 SSL(安全套接层),以实现安全连接。SSL 会对客户端和服务器之间传输的数据进行加密,防止数据被窃听和篡改。
首先,我们需要生成 SSL 证书和密钥。我们将使用 openssl
命令行工具来完成此操作。
在 LabEx 虚拟机中打开你的终端。默认目录是 ~/project
。
我们将创建一个目录来存储 SSL 证书和密钥。执行以下命令:
mkdir ssl
cd ssl
现在,让我们生成服务器密钥:
sudo openssl genrsa 2048 > server-key.pem
接下来,生成证书签名请求(CSR):
sudo openssl req -new -key server-key.pem -out server-req.pem
你会被要求输入一些信息,如国家名称、州、城市、组织名称等。你可以输入合适的值,也可以留空。对于“通用名称”,输入 localhost
或服务器的主机名/IP 地址。
现在,对证书请求进行签名以创建 SSL 证书:
sudo openssl x509 -days 365 -in server-req.pem -signkey server-key.pem -out server-cert.pem
此命令会创建一个有效期为 365 天的自签名证书。
接下来,生成客户端密钥:
sudo openssl genrsa 2048 > client-key.pem
生成客户端证书签名请求(CSR):
sudo openssl req -new -key client-key.pem -out client-req.pem
你会被要求输入与服务器 CSR 类似的信息。
现在,对客户端证书请求进行签名:
sudo openssl x509 -days 365 -in client-req.pem -signkey client-key.pem -out client-cert.pem
最后,生成 CA(证书颁发机构)密钥和证书:
sudo openssl genrsa 2048 > ca-key.pem
sudo openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem
现在,~/project/ssl
目录下有以下文件:
server-key.pem
server-cert.pem
client-key.pem
client-cert.pem
ca-key.pem
ca-cert.pem
接下来,我们需要配置 MySQL 以使用这些 SSL 证书。
编辑 MySQL 配置文件。其位置可能因 MySQL 安装方式而异,但通常位于 /etc/mysql/my.cnf
或 /etc/my.cnf
。由于我们是在 Docker 容器中,我们将在 ~/project
目录下创建一个 my.cnf
文件,并将其挂载到容器中。
在 ~/project
目录下创建一个名为 my.cnf
的文件:
cd ~/project
nano my.cnf
在 my.cnf
文件中添加以下内容:
[mysqld]
ssl-cert=/var/lib/mysql/ssl/server-cert.pem
ssl-key=/var/lib/mysql/ssl/server-key.pem
ssl-ca=/var/lib/mysql/ssl/ca-cert.pem
require_secure_transport=ON
重要提示: my.cnf
文件中的路径是相对于 MySQL 容器的。我们需要将证书复制到容器内的正确位置。由于我们无法直接访问容器的文件系统,在本次实验中我们将跳过此步骤。require_secure_transport=ON
设置会强制所有连接使用 SSL。
现在,让我们重启 MySQL 服务器。由于我们不能使用 systemctl
,在本次实验中我们将跳过重启步骤。在实际场景中,你需要重启 MySQL 服务器以使更改生效。
最后,让我们使用 SSL 连接到 MySQL 服务器。
mysql --ssl-ca=~/project/ssl/ca-cert.pem --ssl-cert=~/project/ssl/client-cert.pem --ssl-key=~/project/ssl/client-key.pem -u root -p
当提示输入密码时,输入 root 密码。
要验证连接是否使用了 SSL,请执行以下 SQL 命令:
SHOW STATUS LIKE 'Ssl_cipher';
如果 Value
列显示了一个密码套件,那么连接正在使用 SSL。
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| Ssl_cipher | TLS_AES_256_GCM_SHA384 |
+---------------+-----------------------+
1 row in set (0.00 sec)
如果 Value
列为空,那么连接没有使用 SSL。
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Ssl_cipher | |
+---------------+-------+
1 row in set (0.00 sec)