参考网址(mysql5.7版本的配置过程和测试过程):http://mp.weixin.qq.com/s/320zgw4GeMM3nfvv7FQdgQ



下方是mysql5.6版本的SSL功能配置过程

******. 背景
在生产环境下,安全总是无法忽视的问题,数据库安全则是重中之重,因为所有的数据都存放在数据库中当使用非加密方式连接MySQL数据库时,在网络中传输的所有信息都是明文的,可以被网络中所有人截取,敏感信息可能被泄露。在传送敏感信息(如密码)时,可以采用SSL连接的方式。


****** MySQL 连接方式
  UNIX本地套接字连接
  TCP非SSL连接网络套接字连接
  TCP的SSL安全连接


******. SSL 简介
 SSL指的是SSL/TLS,其是一种为了在计算机网络进行安全通信的加密协议。假设用户的传输不是通过SSL的方式,那么其在网络中以明文的方式进行传输,而这给别有用心的人带来了可乘之机。所以,现在很多网站其实默认已经开启了SSL功能(不仅仅是web服务,数据库的连接也需要。尤其适用于电商数据库)。


****开启SSL功能后的缺点

开启SSL后,数据库QPS平均降低了23%左右,相对还是比较影响性能的。从SSL实现方式来看,建立连接时需要进行握手、加密、解密等操作。所以耗时基本都在建立连接阶段,这对于使用短链接的应用程序可能产生更大的性能损耗,比如采用PHP开发。不过如果使用连接池或者长连接可能会好许多。


*****试用场景

  1)对于非常敏感核心的数据,或者QPS本来就不高的核心数据,可以采用SSL方式保障数据安全性;

  2)对于采用短链接、要求高性能的应用,或者不产生核心敏感数据的应用,性能和可用性才是首要,建议不要采用SSL方式。





##下方生成证书和私钥的过程需要输入相应的信息,具体原理和含义请看:

####具体过程如下########################

1、查看是否启用了ssl功能:

mysql> show variables like 'have%ssl%'; 
 +---------------+----------+ 
 | Variable_name | Value    | 
 +---------------+----------+ 
 | have_openssl  | DISABLED | 
 | have_ssl      | DISABLED |

2、生成服务端、客户端、CA的证书和私钥。

#######CA 私钥和证书####

openssl genrsa 2048 > ca-key.pem ##生成私钥,用于生成CA的自签证书。CA自己有了证书之后才能给别人签发证书

openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem  ##生成CA的证书(ca.pem)和私钥(ca-key.pem),用于签署校验服务端和客户端的证书。


#######MySQL 服务器 私钥和证书########

openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem  ##服务端生成证书签发请求,CA将会签发server-req.pem证书请求。

openssl rsa -in server-key.pem -out server-key.pem   ##私钥转换为 RSA 私钥文件格式。加密方式更安全

openssl x509 -req -in server-req.pem -days 3600   -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem  ##签发下服务端的证书


######客户端的 RSA 私钥和数字证书########

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  ##签署生成客户端的证书


3、配置mysql的SSL功能

1)cp  ca.pem  server-*.pem   /PATH_TO_MYSQL_DATADIR  ##拷贝CA证书、服务端的证书、密钥,到mysql的数据目录下。

2)chown   mysql.mysql   /PATH_TO_MYSQL_DATADIR/{ca,server*}.pem  ##修改下证书、密钥的属主属组

3)vim /etc/my.cnf  #####配置 MySQL 服务的配置文件

4)service mysqld restart  ## 重启mysql服务

[mysqld] 
 ssl-ca=/PATH_TO_MYSQL_DATADIR/ca.pem 
 ssl-cert=/PATH_TO_MYSQL_DATADIR/server-cert.pem 
 ssl-key=/PATH_TO_MYSQL_DATADIR/server-key.pem


5)查看下ssl功能是否启用。如下表示已经启用

mysql> show variables like 'have%ssl%'; 
 +---------------+-------+ 
 | Variable_name | Value | 
 +---------------+-------+ 
 | have_openssl  | YES  | 
 | have_ssl      | YES  | 
 +---------------+-------+


6)mysql> grant all on *.* to 'ssl_test'@'%' identified by '123' require SSL; ##建立需要ssl更能才能连接的账户。注意其他的用户不影响的。


7)mysql -h HOST_IP  -ussl_test  --ssl-cert=client-cert.pem --ssl-key=client-key.pem ##使用客户端的证书和私钥才可以连接,如果去掉是不行的。


 8)mysql> \s    ##连接上看下当前会话是不是已经使用了ssl功能

SSL:            Cipher in use is DHE-RSA-AES256-SHA   ##如此,则已经启用了



4、其它开发语言使用SSL功能连接测试:这里以PHP为例,连接测试SSL功能。

直接上程序:要求安装php*-mysqlnd库(注意版本要在5.6.16之上,这个就是下边程序使用的函数的库),php版本 > 5.6.16,否则没办法使用私有CA来连接数据库(低版本的无法跳过验证服务端证书的环节即不支持MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT 这个宏)。

yum install php56w -y ##升级下php
php -v ##验证下php版本
yum install php56w-mysqlnd -y ##安装msyqli的库。


<?php
 error_reporting(E_ALL);
 ini_set("display_errors", "1");

 $link = mysqli_init();
 if (!$link) {
     die('mysqli_init failed');
 }



##各个参数的含义请自行查手册
 mysqli_ssl_set($link,'/tmp/mysqlSSL/client-key.pem','/tmp/mysqlSSL/client-cert.pem','/tmp/mysqlSSL/ca.pem',NULL,NULL);


 ###最好用这种方式连接,特别强调MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT 这个宏是控制php程序不对服务端的证书进行校验,因为我用的是私有CA。不是花钱买的(那也是很好用的)。更加注意的是,这个MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT if (!$link->real_connect('[10.1.9.138]', 'ssl_test', '123456', 'mysql', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT)) {
      echo "error";
 }
 else{
     echo 'Success... ' . mysqli_get_host_info($link) . "\n";
 }



 $sql = "show variables like '%ssl%'";
 if ($result = $link->query($sql)) {
     while ($row = $result->fetch_assoc()) {
         echo $row['Value'] . "\n";
     }
 }


 mysqli_close($link);