前提:已安装好数据库,这里以mysql5.7为例

例如:数据库用户名root   密码:123456

数据库data目录:/usr/local/mysql/data 

登录mysql命令:mysql -uroot -p 

输入密码:123456

Mysql导入证书并开启SSL

一、查看服务端mysql环境

1.查看是否开启了ssl,"have_ssl" 为YES的时候,数据库是开启加密连接方式的

show global variables like '%ssl%';

2.查看数据库版本

select version();

3.查看数据库端口

show variables like 'port';

3306 

4.查看数据库存放路径

show variables like 'datadir';

/usr/local/mysql/data 

二.生成证书

通过openssl制作生成证书

1.生成一个CA私钥

openssl genrsa 2048 > ca-key.pem

2.通过CA私钥生成数字证书

openssl req -new -x509 -nodes -days 99999 -key ca-key.pem -out ca.pem

3.创建mysql服务器私钥和请求证书

openssl req -newkey rsa:2048 -days 99999 -nodes -keyout server-key.pem -out server-req.pem

4.将私钥转换为RSA私钥文件格式

openssl rsa -in server-key.pem -out server-key.pem

5.用CA证书生成一个服务器的数字证书

openssl x509 -req -in server-req.pem -days 99999 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

6.创建客户端的RSA私钥和数字证书

openssl req -newkey rsa:2048 -days 99999 -nodes -keyout client-key.pem -out client-req.pem

注意:这里需要填入配置信息

Country Name (2 letter code) [AU]:cn 国家名(2个字母的代号)

State or Province Name (full name) [Some-State]:cq 省

Locality Name (eg, city) []:cq 市

Organization Name (eg, company) [Internet Widgits Pty Ltd]:gs 公司名

Organizational Unit Name (eg, section) []:gs  组织或部门名

Common Name (eg, YOUR name) []:doris_ca  域名或自己名字(ca证书不要用跟服务端证书或者客户端证书一个common name 会报错!)

Email Address []:   邮箱地址(不填直接回车)

A challenge password []:123456 密码

An optional company name []:gs  公司名

注意:这里的Common Name字段需要填写应用服务器的ip或域名,也就是指连接服务器的ip

例如:https://xxx.cn

7.将生成的私钥转换为RAS私钥文件格式

openssl rsa -in client-key.pem -out client-key.pem

8.用CA证书来生成一个客户端的数字证书

openssl x509 -req -in client-req.pem -days 99999 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

注意:将生成后的客户端证书拷贝到应用服务器上,client-*   (如果程序跟数据库不在同一服务器时)

9.查看所有的ssl文件

ca-key.pem  
ca.pem
client-cert.pem
client-key.pem
client-req.pem
server-cert.pem
server-key.pem
server-req.pem

 10.验证证书

openssl verify -CAfile ca.pem server-cert.pem client-cert.pem

输出结果如下,即为通过:

server-cert.pem: OK

client-cert.pem: OK  

如输出结果报错如下:

问题2:error 18 at 0 depth lookup:self signed certificate

mysql5.7.18开启ssl mysql数据库开启ssl_mysql开启ssl优缺点

需要检查在生产证书时,求你填写的 Common Name

解决方案:

当你在创建ca.csr, server.csr, client.csr时 要求你填写的 Common Name。

ca.pem 的common name 不能和server-cert.pem, client-cert.pem填的相同

三、数据库配置ssl证书

1.将CA证书和服务端ssl文件至mysql数据目录

cp ca.pem server-*.pem /usr/local/mysql/data

注意:/usr/local/mysqldata是数据库的路径,在查看环境时收集到,根据实际情况更换

2.修改msql数据库目录的CA证书和服务端ssl文件所属用户和组

必要时将权限也设置一下:chmod 775 ca.pem server-cert.pem server-key.pem

chown -v mysql.mysql  /usr/local/mysql/data{ca,server*}.pem

3.修改mysql配置文件,添加ssl调用配置

vi /etc/my.cnf
[client]
ssl-cert = /usr/local/mysql/data/client-cert.pem 
ssl-key = /usr/local/mysql/data/client-key.pem
注意:如果是做了主从,需要把主的证书拷贝到从
    
[mysqld]
ssl-ca=/usr/local/mysql/data/ca.pem
ssl-cert=/usr/local/mysql/data/server-cert.pem
ssl-key=/usr/local/mysql/data/server-key.pem

4.重启mysql服务,检查数据库ssl是否开启状态,have_openssl 与 have_ssl 值都为YES表示ssl开启成功

service mysqld restart
show variables like '%ssl%';
show variables like 'have%ssl%';

在linux端用root账号进入mysql命令行界面,查看当前版本mysql数据库是否支持ssl,如果出现以下结果表示支持,如果没有考虑更换版本,或者编译一个带有SSL版本的mysql

mysql5.7.18开启ssl mysql数据库开启ssl_ssl_02

查看用户是否使用SSL连接

use mysql;

select ssl_type from user where user='test' and host='%';

mysql5.7.18开启ssl mysql数据库开启ssl_ssl_03

 强制某用户使用SSL连接

ALTER USER 'test'@'%' REQUIRE SSL;

FLUSH PRIVILEGES;

mysql5.7.18开启ssl mysql数据库开启ssl_服务器_04

5.测试ssl可用性

grant all on *.* to 'test'@'127.0.0.1' identified by 'test' require SSL;

注意:如果不在本服务器操作,需要将127.0.0.1更换为应用服务器的ip

测试不使用ssl能否连接上

mysql -utest -p -h10.22.xx.xx --ssl-mode=DISABLED;

mysql5.7.18开启ssl mysql数据库开启ssl_mysql_05

取消用户使用ssl连接

update user set ssl_type='' where user='test' and host='%';

FLUSH PRIVILEGES;

mysql5.7.18开启ssl mysql数据库开启ssl_服务器_06

6.密码连接测试

mysql -utest -ptest -h 127.0.0.1 
此时会报错:
ERROR 1045 (28000): Access denied for user 'test1'@'124.222.67.220' (using password: YES)
YES代表需要密码,但没有通过ssl验证

注意:如果MySQL端口不是3306,需要在后面加参数(-P 端口号)

7.通过客户端密钥与证书ssl+密码连接测试,并查看属性

mysql -utest -ptest -h 127.0.0.1 --ssl-cert=client-cert.pem --ssl-key=client-key.pem
进入数据库后,\s查看属性
加密前:
SSL: Not in use
加密后:
SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384

注意:启动时,需要在client-cert.pem和client-key.pem证书目录下启动,或者在启动时更改证书的路径

例:mysql -utest -ptest -h 127.0.0.1 --ssl-cert=/usr/local/mysql/data/client-cert.pem --ssl-key=/usr/local/mysql/data/client-key.pem

四、JAVA客户端连接数据库

1.要另外指定客户端需要使用加密连接,请启用 require_secure_transport系统变量,ON为开启,OFF默认关闭:

vi /etc/my.cnf
在mysqld下添加
[mysqld]
ssl-ca=/usr/local/mysql/data/ca.pem
ssl-cert=/usr/local/mysql/data/server-cert.pem
ssl-key=/usr/local/mysql/data/server-key.pem
require_secure_transport=ON

查询用户是否强制ssl验证 :select Host,user,ssl_type from User;

mysql5.7.18开启ssl mysql数据库开启ssl_服务器_07

要确定当前与服务器的连接是否使用加密,请检查Ssl_cipher状态变量的会话值 。如果该值为空,则连接未加密。否则,连接被加密并且该值指示加密密码。例如:

mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
+---------------+---------------------------+

 对于mysql客户端,另一种方法是使用STATUSor\s 命令并检查该SSL行:

mysql> \s
...
SSL: Not in use
...


mysql> \s
...
SSL: Cipher in use is DHE-RSA-AES128-GCM-SHA256
...

2.使用jdk自带的keytool工具导入mysql客户端证书到密钥仓库,并生成秘钥仓库文件

1.确认是否安装了jdk,并配置了环境变量,如果没有配置环境变量,只能到jdk安装的目录下使用keytoll工具

2.执行shell命令将ca.pem文件导入到密钥仓库,并生成密钥仓库文件

keytool -importcert -alias Cacert -file ca.pem -keystore truststoremysql -storepass 123456


openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -name "mysqlclient" -passout pass:123456 -out client-keystore.p12


keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore keystoremysql -deststoretype JKS -deststorepass 123456

 1.找服务端提供三个原始文件

 

mysql5.7.18开启ssl mysql数据库开启ssl_SSL_08

2.生成truststore文件

keytool -importcert -alias Cacert -file ca.pem -keystore truststoremysql -storepass 123456

3.生成keystore文件
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -name "mysqlclient" -passout pass:123456

keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore keystoremysql -deststoretype JKS -deststorepass 123456

以上两个文件生成的参数可以自己修改,windows环境中没有openssl,在linux环境中执行。红色部分的参数是后面配置要用到的

mysql5.7.18开启ssl mysql数据库开启ssl_服务器_09

五、JAVA客户端连接数据库

1.正常的请求如下


spring.datasource.url = jdbc:mysql://1.2.3.4:3306/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false


url: jdbc:mysql://10.0.0.199:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=true&userAffectRows=true
username: root
password: 123456

2.ssl双向认证的请求如下

server:
  port: 10000

ssl:
  cert:
    path: /usr/local/mysql/data
  config: true&verifyServerCertificate=true&requireSSL=true&clientCertificateKeyStoreUrl=file:${ssl.cert.path}/keystoremysql&clientCertificateKeyStorePassword=123456&trustCertificateKeyStoreUrl=file:${ssl.cert.path}/truststoremysql&trustCertificateKeyStorePassword=123456

spring:
  application:
    name: dissertation
  devtools:
    restart:
      enabled: true
  thymeleaf:
    cache: true
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/dissertation?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=${ssl.config}
    username: root
    password: 123456


ssl.cert.path = /home/app/cert
ssl.config = true&verifyServerCertificate=true&requireSSL=true&clientCertificateKeyStoreUrl=file:${ssl.cert.path}/keystoremysql&clientCertificateKeyStorePassword=123456&trustCertificateKeyStoreUrl=file:${ssl.cert.path}/truststoremysql&trustCertificateKeyStorePassword=123456 
url: jdbc:mysql://127.0.0.1:3306/dissertation?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=${ssl.config}
username: root
password: 123456


因为加上ssl认证后url太长了,所以提取了两个变量。

ssl.cert.path表示生成的两个证书文件存放路径

ssl.config的value里根据证书生成的参数对应修改,如果不需要ssl认证值设置为false即可。 以上就完成了客户端的配置,如常启动服务,验证连接正常即可。