使用Stunnel为MySQL Server建立SSL隧道

笔者接手的一个项目有如下需求:

两台主机A和B,A上运行一个MySQL服务器和一套基于PHP的、以MySQL为数据库的CMS;B上除MySQL服务器外,其他皆与A相同。

要求B能安全地(通过SSL)连接A上的MySQL服务器,而这个CMS本身不支持MySQL over SSL

Stunnel可以提供一个安全的SSL隧道,理论上可以承载任何应用层协议——包括MySQL。


以下操作在A和B上执行。

OpenSSL的目录需根据实际情况设置,Stunnel最高支持OpenSSL 1.1.1-dev

tar zxvf stunnel-5.44.tar.gz
cd stunnel-5.44/

#编译安装至/opt/stunnel,配置文件存放于/etc/stunnel
./configure --prefix= --exec-prefix=/opt/stunnel --with-ssl=/opt/openssl-1.1.0g LDFLAGS="-Wl,--rpath=/opt/openssl-1.1.0g/lib -L/opt/openssl-1.1.0g/lib -lssl -lcrypto"
make
make install

建立systemd service文件/lib/systemd/system/stunnel.service,内容如下:

[Unit]
Description=SSL tunnel daemons
After=network.target
After=syslog.target
 
[Install]
WantedBy=multi-user.target
Alias=stunnel.target

[Service]
Type=forking
ExecStart=/opt/stunnel/bin/stunnel /etc/stunnel/stunnel.conf
ExecStop=/bin/kill -TERM $MAINPID
ExecReload=/bin/kill -USR1 $MAINPID
 
# Give up if ping don't get an answer
TimeoutSec=600
 
Restart=always
PrivateTmp=false

执行systemctl daemon-reload令更改生效

编辑A机(服务器端)的stunnel配置文件(/etc/stunnel/stunnel.conf,下同)

pid = /var/run/stunnel4/stunnel4.pid
#只允许使用AES-GCM且具有前向安全性的加密套件
ciphers = ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256
#只允许使用TLS 1.2
options = NO_SSLv2
options = NO_SSLv3
options = NO_TLSv1
options = NO_TLSv1.1

options = CIPHER_SERVER_PREFERENCE
options = DONT_INSERT_EMPTY_FRAGMENTS
renegotiation = no

[mysql]
#SSL证书与私钥
cert = /path/to/cert_with_intermediate_CA.cer
key = /path/to/private_key.key
#SSL监听端口
accept  = 6033
#MySQL监听地址及端口
connect = 127.0.0.1:3306

编辑B机的Stunnel配置文件

pid = /var/run/stunnel4/stunnel4.pid

[mysql]
#本地(明文)监听端口
accept  = 127.0.0.1:3306
#远程(SSL)地址及端口
connect = {A_IP_ADDR}:6033
#使用客户端模式
client = yes

编辑完后,A机和B机分别执行systemctl restart stunnel4.service以重启Stunnel


测试:

在B机执行openssl s_client -crlf -connect {A_IP_ADDR}:6033,若出现类似如下报文,则A机配置无问题。

j
5.5.5-10.0.31-MariaDB-0ubuntu0.16.04.2?J%wLÿ? UD6!Clu)iWY9mysql_native_password

可以在命令后添加-ssl3|-tls1|-tls1_1以测试是否确实禁用低版本SSL协议。

在B机执行telnet 127.0.0.1 3306,若返回类似报文,则B机配置也无问题。


此时,B机上的PHP程序,数据库连接部分保持与A机上的相同即可。