14.9.2 TLS/SSL与加密传输配置

在 ProxySQL 中启用 TLS/SSL 的目标是保证客户端到 ProxySQL、ProxySQL 到后端 MySQL 的链路加密,并降低中间人攻击风险。本节给出完整的证书准备、安装配置、验证、排错与练习。

原理草图(双链路加密)

文章图片

一、证书准备与目录权限(示例:自签 CA)#

说明:以下命令在 ProxySQL 主机执行,生成 CA、服务端证书。
命令解释:openssl req 生成证书请求;x509 用 CA 签发;chmod 600 限制私钥权限。

# 1) 目录准备
sudo mkdir -p /etc/proxysql/ssl
sudo chown -R proxysql:proxysql /etc/proxysql/ssl
sudo chmod 700 /etc/proxysql/ssl

# 2) 生成 CA
openssl genrsa -out /etc/proxysql/ssl/ca.key 4096
openssl req -x509 -new -nodes -key /etc/proxysql/ssl/ca.key \
  -subj "/C=CN/ST=BJ/L=BJ/O=Ops/OU=ProxySQL/CN=ProxySQL-CA" \
  -days 3650 -out /etc/proxysql/ssl/ca.crt

# 3) 生成 ProxySQL 证书
openssl genrsa -out /etc/proxysql/ssl/proxysql.key 2048
openssl req -new -key /etc/proxysql/ssl/proxysql.key \
  -subj "/C=CN/ST=BJ/L=BJ/O=Ops/OU=ProxySQL/CN=proxysql.local" \
  -out /etc/proxysql/ssl/proxysql.csr
openssl x509 -req -in /etc/proxysql/ssl/proxysql.csr \
  -CA /etc/proxysql/ssl/ca.crt -CAkey /etc/proxysql/ssl/ca.key -CAcreateserial \
  -days 825 -out /etc/proxysql/ssl/proxysql.crt

# 4) 权限收敛
sudo chmod 600 /etc/proxysql/ssl/*.key
sudo chmod 644 /etc/proxysql/ssl/*.crt

二、ProxySQL 前端 TLS 配置与安装落地#

说明:ProxySQL 通常已安装,此处配置 SSL 监听与安全策略。
命令解释:INSERT/UPDATE 写入运行时配置,LOAD 生效到运行内存,SAVE 持久化到磁盘。

-- 进入 ProxySQL 管理端(示例)
-- mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- 1) 配置前端监听启用 TLS
UPDATE global_variables SET variable_value='1' WHERE variable_name='mysql-have_ssl';
UPDATE global_variables SET variable_value='/etc/proxysql/ssl/ca.crt' WHERE variable_name='mysql-ssl_p2s_ca';
UPDATE global_variables SET variable_value='/etc/proxysql/ssl/proxysql.crt' WHERE variable_name='mysql-ssl_p2s_cert';
UPDATE global_variables SET variable_value='/etc/proxysql/ssl/proxysql.key' WHERE variable_name='mysql-ssl_p2s_key';

-- 2) 约束协议与套件(示例:禁用 TLS1.0/1.1)
UPDATE global_variables SET variable_value='TLSv1.2,TLSv1.3' WHERE variable_name='mysql-ssl_protocols';
UPDATE global_variables SET variable_value='ECDHE+AESGCM:TLS_AES_256_GCM_SHA384' WHERE variable_name='mysql-ssl_ciphers';

-- 3) 生效与保存
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

验证命令与预期效果

# 预期:显示证书链与协商协议(例如 TLSv1.3)
openssl s_client -connect 127.0.0.1:6033 -CAfile /etc/proxysql/ssl/ca.crt -tls1_2
-- 预期:统计 SSL 连接
SELECT * FROM stats_mysql_connection_pool WHERE ConnUsed > 0\G

三、ProxySQL 到 MySQL 后端 TLS 配置#

说明:MySQL 后端需启用 SSL,ProxySQL 后端连接需启用 ssl=1 并指定 CA。

MySQL 后端配置(my.cnf)

[mysqld]
require_secure_transport=ON
ssl_ca=/etc/mysql/ssl/ca.crt
ssl_cert=/etc/mysql/ssl/mysql.crt
ssl_key=/etc/mysql/ssl/mysql.key

ProxySQL 后端参数

-- 1) 后端服务器启用 SSL
UPDATE mysql_servers SET use_ssl=1 WHERE hostgroup_id=10;

-- 2) 后端 CA(如不同 CA 按需设置)
UPDATE global_variables SET variable_value='/etc/proxysql/ssl/ca.crt' WHERE variable_name='mysql-ssl_p2s_ca';

-- 3) 生效
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

验证命令

-- 预期:后端连接使用 SSL
SELECT hostgroup, srv_host, status, ConnUsed, Queries
FROM stats_mysql_connection_pool
WHERE use_ssl=1;

四、常见排错与命令解释#

1) 证书链不完整

# 解释:检查证书链是否包含中间证书
openssl verify -CAfile /etc/proxysql/ssl/ca.crt /etc/proxysql/ssl/proxysql.crt

2) 主机名不匹配

# 解释:查看证书 CN 与 SAN 是否匹配访问域名
openssl x509 -in /etc/proxysql/ssl/proxysql.crt -noout -text | grep -E "Subject:|DNS:"

3) 权限不足导致读取私钥失败

# 解释:确保 proxysql 用户可读私钥
sudo -u proxysql ls -l /etc/proxysql/ssl/proxysql.key

4) 协议不兼容

# 解释:测试不同 TLS 版本
openssl s_client -connect 127.0.0.1:6033 -tls1_2
openssl s_client -connect 127.0.0.1:6033 -tls1_3

五、性能影响与优化示例#

说明:TLS 握手耗时可通过连接池与复用降低。

-- 调大连接池与复用参数(示例)
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-max_connections';
UPDATE global_variables SET variable_value='1' WHERE variable_name='mysql-session_reuse';
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

六、练习#

1) 使用自签 CA 为 ProxySQL 与 MySQL 后端签发证书,完成双链路 TLS,使用 openssl s_client 验证。
2) 故意将证书 CN 改为错误域名,观察客户端连接报错并记录排错步骤。
3) 禁用 TLS1.0/1.1 后,用旧客户端连接,记录失败原因并给出兼容策略。