内容:MySQL SSL 加密链接;MySQL 强制证书登录;
MySQL v5.7
代码在本地测试修改,使用到了线上的数据库。开放端口之后,虽然端口改了,密码强度也够可以。但终究不放心;
所以决定本地使用 SSL 安全链接访问远程数据库,并且连接远程数据库强制要求客户端提供证书;
(1). 检查 MySQL 是否支持 SSL
https://dev.mysql.com/doc/refman/5.7/en/openssl-versus-yassl.html
根据官方描述:
MySQL Enterprise Edition binary distributions,编译使用的 OpenSSL 库;
MySQL Community Edition binary distributions,使用的是 yaSSL 库。(我们经常用的就是 Community Edition。我本地测试用的就是这个版本)
MySQL Community Edition source distributions,自己编译的同学就自己看着办吧,编译的时候记得加参数;
参照官方文档「7.4.2 Building MySQL with Support for Secure Connections」
检查是否支持 SSL,通过查看 have_ssl 系统变量:
mysql> SHOW VARIABLES LIKE 'have_ssl'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_ssl | YES | +---------------+-------+
如果想看使用了 OpenSSL 还是 yaSSL:
mysql> SHOW STATUS LIKE 'Rsa_public_key'; -- Empty set (0.00 sec)
如果输出为“Empty set (0.00 sec)”则表示使用了 yaSSL 库;如果输出不为空,则表示使用了 OpenSSL 库;
(2). 检查 SSL 的版本
https://dev.mysql.com/doc/refman/5.7/en/secure-connection-protocols-ciphers.html
MySQL 的安全链接使用的是 TLS 协议:
如果使用了 yaSSL 库, MySQL 支持 TLSv1、TLSv1.1;
查看 MySQL 支持的 TLS 协议版本:
mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version'; -- +---------------+---------------+ -- | Variable_name | Value | -- +---------------+---------------+ -- | tls_version | TLSv1,TLSv1.1 | -- +---------------+---------------+ -- 1 row in set (0.00 sec)
如果要修改 tls_version 的值,需要修改 my.cnf。在 mysqld 章节加入参数,如下:
[mysqld] tls_version=TLSv1.1,TLSv1.2
(3). 配置安全链接
创建 SSL 相关文件
创建 CA 证书
openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem
创建服务端证书
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem openssl rsa -in server-key.pem -out server-key.pem openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
创建客户端证书
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem openssl rsa -in client-key.pem -out client-key.pem openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
配置 MySQL
[mysqld] ssl-ca=ca.pem ssl-cert=server-cert.pem ssl-key=server-key.pem
(4). 检查配置是否成功
使用 SSL 连接 MySQL:
mysql --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -u root -p -hlocalhost
使用 “Ssl_cipher” 变量来检查当前链接是否加密:
mysql> SHOW STATUS LIKE 'Ssl_cipher'; -- +---------------+--------------------+ -- | Variable_name | Value | -- +---------------+--------------------+ -- | Ssl_cipher | DHE-RSA-AES256-SHA | -- +---------------+--------------------+ -- 1 row in set (0.01 sec)
如果没有使用 SSL 链接,“Ssl_cipher” 的值为空;
也可以使用 \s 来查看:
mysql> \s ...... SSL: Cipher in use is DHE-RSA-AES256-SHA ......
如果没有使用 SSL 链接,“SSL: Not in use”;
(5). 设置帐号登录时提供证书
alter user demo@'%' identified by 'demo,&r' require X509;
(6). 关于 PHP 中使用证书访问 MySQL
“You are enforcing ssl conection via unix socket. Please consider switching ssl off as it does not make connection via unix socket any more secure.” – 如果通过 unix socket 访问数据库,鉴于是本地连接,未跨网络,因此无需使用 ssl 连接;