查看是否支持 SSL

首先在 MySQL 上执行如下命令, 查询是否 MySQL 支持 SSL:

  1. mysql> SHOW VARIABLES LIKE 'have_ssl';
  2. +---------------+-------+
  3. | Variable_name | Value |
  4. +---------------+-------+
  5. | have_ssl | YES |
  6. +---------------+-------+
  7. 1 row in set (0.02 sec)

have_sslYES 时, 表示此时 MySQL 服务已经支持 SSL 了. 如果是 DESABLE, 则需要在启动 MySQL 服务时, 使能 SSL 功能.

使用 OpenSSL 创建 SSL 证书和私钥

首先我们需要使用 openssl 来创建服务器端的证书和私钥. 我使用的 openssl 版本为:

  1. >>> /usr/local/Cellar/openssl/1.0.2j/bin/openssl version
  2. OpenSSL 1.0.2j 26 Sep 2016

新建一个 ~/temp/cert 目录, 用于存放生成的证书和私钥

  1. mkdir ~/temp/cert
  2. cd ~/temp/cert

创建 CA 私钥和 CA 证书

然后, 我们先来生成一个 CA 私钥:

  1. openssl genrsa 2048 > ca-key.pem

当有了一个 CA 私钥, 我们接下来就可以使用这个私钥生成一个新的数字证书:

  1. openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem

执行这个命令时, 会需要填写一些问题, 随便填写就可以了. 例如:

  1. >>> openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem
  2. You are about to be asked to enter information that will be incorporated
  3. into your certificate request.
  4. What you are about to enter is what is called a Distinguished Name or a DN.
  5. There are quite a few fields but you can leave some blank
  6. For some fields there will be a default value,
  7. If you enter '.', the field will be left blank.
  8. -----
  9. Country Name (2 letter code) [AU]:CN
  10. State or Province Name (full name) [Some-State]:Beijing
  11. Locality Name (eg, city) []:Beijing
  12. Organization Name (eg, company) [Internet Widgits Pty Ltd]:xys
  13. Organizational Unit Name (eg, section) []:xys
  14. Common Name (e.g. server FQDN or YOUR name) []:xys
  15. Email Address []:yongshun1228@gmail.com

执行上述命令后, 我们就有了一个 CA 私钥和一个 CA 证书.

创建服务器端的 RSA 私钥和数字证书

接着, 我们需要创建服务器端的私钥和一个证书请求文件, 命令如下:

  1. openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem

上面这个命令会生成一个新的私钥(server-key.pem), 同时会使用这个新私钥来生成一个证书请求文件(server-req.pem).

上面这个命令同样需要回答几个问题, 随便填写即可. 不过需要注意的是, A challenge password 这一项需要为空.

即:

  1. >>> openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem
  2. Generating a 2048 bit RSA private key
  3. .................+++
  4. ..+++
  5. writing new private key to 'server-key.pem'
  6. -----
  7. You are about to be asked to enter information that will be incorporated
  8. into your certificate request.
  9. What you are about to enter is what is called a Distinguished Name or a DN.
  10. There are quite a few fields but you can leave some blank
  11. For some fields there will be a default value,
  12. If you enter '.', the field will be left blank.
  13. -----
  14. Country Name (2 letter code) [AU]:CN
  15. State or Province Name (full name) [Some-State]:Beijing
  16. Locality Name (eg, city) []:Beijing
  17. Organization Name (eg, company) [Internet Widgits Pty Ltd]:xys
  18. Organizational Unit Name (eg, section) []:xys
  19. Common Name (e.g. server FQDN or YOUR name) []:xys
  20. Email Address []:yongshun1228@gmail.com
  21. Please enter the following 'extra' attributes
  22. to be sent with your certificate request
  23. A challenge password []:
  24. An optional company name []:

下一步, 我们需要将生成的私钥转换为 RSA 私钥文件格式:

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

最后一步, 我们需要使用原先生成的 CA 证书来生成一个服务器端的数字证书:

  1. openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

上面的命令会创建以服务器端的数字证书文件.

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

和服务器端所执行的命令类似, 我们也需要为客户端生成一个私钥和证书请求文件, 命令如下:

  1. openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem

同样地, 我们需要将生成的私钥转换为 RSA 私钥文件格式:

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

最后, 我们也需要为客户端创建一个数字证书:

  1. openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

使用工具创建证书与私钥

前面我们介绍了如何使用 OpenSSL 来创建 SSL 连接的私钥和证书文件, 现在我们来看一个更简单的方法.

在 MySQL 5.7 中, 提供了一个名为 mysql_ssl_rsa_setup 的工具, 通过它, 我们可以很方便地创建 SSL 连接所需要的各种文件:

  1. mkdir ~/temp/cert
  2. cd ~/temp/cert
  3. mysql_ssl_rsa_setup --datadir ./

上面的命令中, --datadir 表示生成的文件的目录.

当执行了上述命令后, 也会生成八个文件:

  1. ca-key.pem
  2. ca.pem
  3. client-cert.pem
  4. client-key.pem
  5. private_key.pem
  6. public_key.pem
  7. server-cert.pem
  8. server-key.pem

这些文件和我们使用 OpenSSL 所创建的那八个文件的作用是一样的, 这里就不再详述了.

SSL 配置

在前面的步骤中, 我们已经生成了8个文件, 分别是:

  • ca-cert.pem: CA 证书, 用于生成服务器端/客户端的数字证书.
  • ca-key.pem: CA 私钥, 用于生成服务器端/客户端的数字证书.
  • server-key.pem: 服务器端的 RSA 私钥
  • server-req.pem: 服务器端的证书请求文件, 用于生成服务器端的数字证书.
  • server-cert.pem: 服务器端的数字证书.
  • client-key.pem: 客户端的 RSA 私钥
  • client-req.pem: 客户端的证书请求文件, 用于生成客户端的数字证书.
  • client-cert.pem: 客户端的数字证书.

接下来我们就需要分别配置服务器端和客户端.

服务器端配置

服务器端需要用到三个文件, 分别是: CA 证书, 服务器端的 RSA 私钥, 服务器端的数字证书, 我们需要在 [mysqld] 配置域下添加如下内容:

  1. [mysqld]
  2. ssl-ca=/etc/mysql/ca-cert.pem
  3. ssl-cert=/etc/mysql/server-cert.pem
  4. ssl-key=/etc/mysql/server-key.pem

接着我们还可以更改 bind-address, 使 MySQL 服务可以接收来自所有 ip 地址的客户端, 即:

  1. bind-address = *

当配置好后, 我们需要重启 MySQL 服务, 使能配置.

最后一步, 我们添加一个需要使用 SSL 才可以登录的帐号, 来验证一下我们所配置的 SSL 是否生效:

  1. GRANT ALL PRIVILEGES ON *.* TO 'ssl_test'@'%' IDENTIFIED BY 'ssl_test' REQUIRE SSL;
  2. FLUSH PRIVILEGES;

当配置好后, 使用 root 登录 MySQL, 执行 show variables like '%ssl%' 语句会有如下输出:

  1. mysql> show variables like '%ssl%';
  2. +---------------+-----------------+
  3. | Variable_name | Value |
  4. +---------------+-----------------+
  5. | have_openssl | YES |
  6. | have_ssl | YES |
  7. | ssl_ca | ca.pem |
  8. | ssl_capath | |
  9. | ssl_cert | server-cert.pem |
  10. | ssl_cipher | |
  11. | ssl_crl | |
  12. | ssl_crlpath | |
  13. | ssl_key | server-key.pem |
  14. +---------------+-----------------+
  15. 9 rows in set (0.01 sec)

客户端配置

客户端配置相对简单一些. 首先我们需要拷贝 ca-cert.pem, client-cert.pemclient-key.pem 这三个文件到客户端主机中, 然后我们可以执行如下命令来使用 SSL 连接 MySQL 服务:

  1. mysql --ssl-ca=/path/to/ca-cert.pem --ssl-cert=/path/to/client-cert.pem --ssl-key=/path/to/client-key.pem -h host_name -u ssl_test -p

除了上述的使用命令行方式配置 SSL 外, 我们也可以使用配置文件的方式. 即在 ~/.my.cnf 文件中添加如下内容即可:

  1. [client]
  2. ssl-ca=/path/to/ca-cert.pem
  3. ssl-cert=/path/to/client-cert.pem
  4. ssl-key=/path/to/client-key.pem

当连接成功后, 我们执行如下指令

  1. mysql> \s
  2. --------------
  3. mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper
  4. Connection id: 14
  5. Current database:
  6. Current user: ssl_test@172.17.0.4
  7. SSL: Cipher in use is DHE-RSA-AES256-SHA
  8. Current pager: stdout
  9. Using outfile: ''
  10. Using delimiter: ;
  11. Server version: 5.7.17 MySQL Community Server (GPL)
  12. Protocol version: 10
  13. Connection: test_db via TCP/IP
  14. Server characterset: latin1
  15. Db characterset: latin1
  16. Client characterset: latin1
  17. Conn. characterset: latin1
  18. TCP port: 3306
  19. Uptime: 1 hour 2 min 9 sec
  20. Threads: 1 Questions: 23 Slow queries: 0 Opens: 126 Flush tables: 3 Open tables: 0 Queries per second avg: 0.006
  21. --------------

如果输出中有 SSL: Cipher in use is DHE-RSA-AES256-SHA 之类的信息, 则表示已经使用 SSL 来连接了.

在 Docker 中使能 MySQL SSL 连接

上面我们简单介绍了一下如果使能 MySQL SSL 连接, 那么现在我们使用 Docker 来具体的实战一把吧!

首先拉取最新的 MySQL 镜像:

  1. docker pull mysql

然后需要准备一下挂载到 Docker 容器的目录结构:

  1. >>> cd ~/temp
  2. >>> tree
  3. .
  4. ├── cert
  5. ├── ca-key.pem
  6. ├── ca.pem
  7. ├── client-cert.pem
  8. ├── client-key.pem
  9. ├── private_key.pem
  10. ├── public_key.pem
  11. ├── server-cert.pem
  12. └── server-key.pem
  13. ├── config
  14. └── my.cnf
  15. └── db
  16. 3 directories, 9 files

在 temp 目录下有三个子目录:

  • cert 目录用于存放我们先前生成的证书和私钥信息;
  • config 目录用于存放 MySQL 服务的配置文件
  • db 目录是用于存放 MySQL 的数据.

下一步我们需要使用如下命令启动 MySQL 容器:

  1. docker run --rm --name test_db -p 10000:3306 -e MYSQL_ROOT_PASSWORD=root -v /Users/xiongyongshun/temp/db:/var/lib/mysql -v /Users/xiongyongshun/temp/config:/etc/mysql/conf.d -v /Users/xiongyongshun/temp/cert:/etc/mysql/cert mysql:latest

我们在上面的命令中, 我们分别挂载了 cert, config, db 这三个宿主机上的目录到 MySQL 容器中.

启动了 MySQL 服务后, 可以先使用 root 帐号登录 MySQL, 来检查 MySQL 服务此时是否已经开启了 SSL 功能:

  1. docker run -it --link test_db:test_db --rm mysql sh -c 'exec mysql -u root -p -h test_db'

登录成功后, 我们在 MySQL 中执行如下指令:

  1. mysql> show variables like '%ssl%';
  2. +---------------+---------------------------------+
  3. | Variable_name | Value |
  4. +---------------+---------------------------------+
  5. | have_openssl | YES |
  6. | have_ssl | YES |
  7. | ssl_ca | /etc/mysql/cert/ca-cert.pem |
  8. | ssl_capath | |
  9. | ssl_cert | /etc/mysql/cert/server-cert.pem |
  10. | ssl_cipher | |
  11. | ssl_crl | |
  12. | ssl_crlpath | |
  13. | ssl_key | /etc/mysql/cert/server-key.pem |
  14. +---------------+---------------------------------+
  15. 9 rows in set (0.01 sec)

有上面的输出后, 表明此时 MySQL 服务已经使用 SSL 功能了.

接着下一步, 我们按照前面所提到的, 创建一个仅仅可以使用 SSL 登录的帐号, 来检验我们的配置是否有效:

  1. GRANT ALL PRIVILEGES ON *.* TO 'ssl_test'@'%' IDENTIFIED BY 'ssl_test' REQUIRE SSL;
  2. FLUSH PRIVILEGES;

上面的命令创建了一个帐号名为 ssl_test, 密码为 ssl_test, 并且不限制登录主机 ip 的帐号.

这些都配置成功后, 我们再启动一个 MySQL 客户端容器:

  1. docker run -it --link test_db:test_db --rm -v /Users/xiongyongshun/temp/cert:/etc/mysql/cert mysql sh -c 'exec mysql --ssl-ca=/etc/mysql/cert/ca-cert.pem --ssl-cert=/etc/mysql/cert/client-cert.pem --ssl-key=/etc/mysql/cert/client-key.pem -h test_db -u ssl_test -p'

从上面的这个命令中我们可以看到, 启动 MySQL 客户端容器时, 我们挂载了宿主机的 cert 目录到容器内的 /etc/mysql/cert 目录, 这样在容器中就可以访问到 SSL 私钥和证书文件了. 接着我们在 MySQL 客户端命令行中, 使用 --ssl-ca, --ssl-cert, --ssl-key 这三个参数来指定 SSL 连接所需要的 CA 证书, RSA 私钥和客户端证书.

登录成功后, 我们执行 \s 命令:

  1. mysql> \s
  2. --------------
  3. mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper
  4. Connection id: 5
  5. Current database:
  6. Current user: ssl_test@172.17.0.5
  7. SSL: Cipher in use is DHE-RSA-AES256-SHA
  8. Current pager: stdout
  9. Using outfile: ''
  10. Using delimiter: ;
  11. Server version: 5.7.17 MySQL Community Server (GPL)
  12. Protocol version: 10
  13. Connection: test_db via TCP/IP
  14. Server characterset: latin1
  15. Db characterset: latin1
  16. Client characterset: latin1
  17. Conn. characterset: latin1
  18. TCP port: 3306
  19. Uptime: 6 min 8 sec
  20. Threads: 2 Questions: 10 Slow queries: 0 Opens: 113 Flush tables: 1 Open tables: 106 Queries per second avg: 0.027
  21. --------------

输出中有 SSL: Cipher in use is DHE-RSA-AES256-SHA 信息则说明我们确实是使用了 SSL 连接的 MySQL 服务器.

MySQL 使用 SSL 连接(附 Docker 例子)的更多相关文章

  1. Mysql使用SSL连接

    最近项目中用到了SSL连接,记录一下,环境为windows10,Mysql版本为5.6 查看是否支持 SSL 首先在 MySQL 上执行如下命令, 查询是否 MySQL 支持 SSL: mysql&g ...

  2. SpringBoot设置mysql的ssl连接

    因工作需要,mysql连接需要开启ssl认证,本文主要讲述客户端如何配置ssl连接. 开发环境信息: SpringBoot: 2.0.5.RELEASE mysql-connector-java: 8 ...

  3. MySQL启用SSL连接

    1.手动创建自认证证书 1.1 创建CA证书 openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3600 ...

  4. MySQL的SSL加密连接与性能开销

    本文转载自:http://www.innomysql.net/article/23959.html(只作转载, 不代表本站和博主同意文中观点或证实文中信息) Contents [hide] 1 前言 ...

  5. Java连接mysql——Establishing SSL connection without server's identity verification is not recommended.

    Establishing SSL connection without server's identity verification is not recommended. 出现这个错误的原因是因为m ...

  6. Mysql ssl 连接

    在Azure创建了一个Mysql5.7服务,因为默认使用ssl连接,需要下载Azure的证书,并使用openssl生成客户端的证书.具体流程参考官方文档 大致步骤: 下载根证书, 安装openssl, ...

  7. 关于JDBC技术中,调用MySQL中不建议在没有服务器身份验证的情况下建立SSL连接错误解决

    今天学习到了JBDC前沿:对JDBC编写步骤的封装,出现了一大串红色报错(当然,也不能叫报错,毕竟不是所有的红色都是错误eeror,) 错误如下: Establishing SSL connectio ...

  8. 连接远程docker内的mysql(navicat)

    拉取mysql镜像 docker pull mysql:5.6 查看mysql镜像 docker images | grep mysql 启动mysql容器 docker run -p 3306:33 ...

  9. Mysql 中的SSL 连接

    Mysql 中的SSL 连接 以下来自网络参考和自己测试整理,没有查找相关资料.若有错误之处,欢迎指正. 当前的Mysql 客户端版本基本都不太能支持 caching_sha2_password 认证 ...

随机推荐

  1. Qt Creator的安装与Qt交叉编译的配置

    Qt Creator 的安装 到Qt官网下载Qt Creator  https://www.qt.io/download-open-source/ 其它旧版本点击Achieve连接下载 或登录http ...

  2. Fragment 创建 传递参数 跳转【典例】

    Fragment一定要有一个无参的构造方法! 因为当Activity因屏幕旋转或者因内存不足被系统杀死时,会导致Activity被重新创建,而当Activity被重建时,FragmentManager ...

  3. Sqlite-SQLiteHelper类,操作SQLite数据库

    using System; using System.Data; using System.Text.RegularExpressions; using System.Xml; using Syste ...

  4. PHP快速入门 如何操作MySQL

    1 创建一个新的数据库,注意类型设置为utf8_general_ci 2 在数据库中创建一个新的表,比如叫做tg_user(先从左侧选择刚才创建的数据库) 3 创建第一个字段,自动编号.我们估计网站的 ...

  5. 一个完整的C++程序SpreadSheet - 1) 类的声明和定义

    1. SpreadsheetCell.h #pragma once #include <string> class SpreadsheetCell { public: void setVa ...

  6. Arrays.asList的用法

    使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportOperationException异常说明: ...

  7. postgres时间转换函数

    函数 返回类型 描述 例子 to_char(timestamp, text) text 把时间戳转换成字串 to_char(current_timestamp, 'HH12:MI:SS') to_ch ...

  8. ‘close’ was not declared in this scope

    ‘close’ was not declared in this scope ‘read’ was not declared in this scope ‘sysconf’ was not decla ...

  9. 旧文备份:简单CANOpen 协议说明

    (十年前的旧文,不舍等扔) 创建日期:2005-11-17 修改日期:2005-11-17 文件名称:简单CANOpen 协议说明.doc 作者:winshton 版本:V1.0 (注:本文以24in ...

  10. ip段/数字,如192.168.0.1/24的意思是什么?(转)

    ip段/数字,如192.168.0.1/24的意思是什么? 踩踩 0作者:Admin 发表日期:2013-10-31 复制链接 收藏 首先来了解一下二进制的转换知识: 二进制数转换成十进制数 二进制的 ...