使用SSL加密连接MySQL

在使用TCP/IP连接数据库时,才可能使用到SSL。使用socket登录显然无法支持SSL加密


首先数据库需要开启SSL功能(5.7默认开启,5.6需要手动开启):

mysql> SHOW GLOBAL VARIABLES LIKE 'have_%ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
| have_ssl      | YES   |
+---------------+-------+
2 rows in set (0.01 sec)


MySQL 5.7.6之后的版本

官方推荐在--initialize之后多一步mysql_ssl_rsa_setup操作,生成SSL certificate and key files 和 RSA key-pair files,用于建立SSL安全连接和安全的密码传输。

若在安装过程中未创建过ssl和rsa文件,可以随时利用mysql_ssl_rsa_setup --datadir=XXX 指定数据目录并在该目录下创建认证文件,如下:

-rw------- 1 mysql mysql     1675 Sep 13 16:19 ca-key.pem
-rw-r--r-- 1 mysql mysql     1074 Sep 13 16:19 ca.pem
-rw-r--r-- 1 mysql mysql     1078 Sep 13 16:19 client-cert.pem
-rw------- 1 mysql mysql     1679 Sep 13 16:19 client-key.pem
-rw------- 1 mysql mysql     1675 Sep 13 16:19 private_key.pem
-rw-r--r-- 1 mysql mysql      451 Sep 13 16:19 public_key.pem
-rw-r--r-- 1 mysql mysql     1078 Sep 13 16:19 server-cert.pem
-rw------- 1 mysql mysql     1675 Sep 13 16:19 server-key.pem

重启后,ssl_ca、ssl_cert、ssl_key的文件路径将被确定。此时,未指定require选项的用户也可以使用ssl加密连接入数据库。

mysql> show variables like "%ssl%";
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
9 rows in set (0.00 sec)

此外,CA文件、公钥、私钥需要分发给客户端,以便使用X509方式登录


创建user3,require ssl(该用户将只能使用ssl登录)

mysql> create user user3@'127.0.0.1';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on *.* to 'user3'@'127.0.0.1' require ssl;
Query OK, 0 rows affected, 1 warning (0.00 sec)

指定证书,并使用\s确认

[root@237_21 ~]# mysql -uuser3 -h 127.0.0.1 -P3307 --ssl=1
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.18-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.6.36, for linux-glibc2.5 (x86_64) using  EditLine wrapper

Connection id:		8
Current database:	
Current user:		[email protected]
SSL:			Cipher in use is DHE-RSA-AES256-SHA
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server version:		5.7.18-log MySQL Community Server (GPL)
Protocol version:	10
Connection:		127.0.0.1 via TCP/IP
Server characterset:	utf8mb4
Db     characterset:	utf8mb4
Client characterset:	utf8
Conn.  characterset:	utf8
TCP port:		3307
Uptime:			5 hours 9 min 18 sec

Threads: 1  Questions: 57  Slow queries: 0  Opens: 145  Flush tables: 1  Open tables: 138  Queries per second avg: 0.003
--------------


创建用户user4,require x509(在SSL的基础上,进一步启用X509身份认证)

mysql> create user 'user4'@'127.0.0.1';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all on *.* to 'user4'@'127.0.0.1' require x509;
Query OK, 0 rows affected, 1 warning (0.00 sec)
指定证书登录,并使用\s确认

[root@237_21 ~]# mysql -uuser4 -h 127.0.0.1 -P3307 --ssl-cert=/data/mysql3307/client-cert.pem --ssl-key=/data/mysql3307/client-key.pem 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.18-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.18, for linux-glibc2.5 (x86_64) using  EditLine wrapper

Connection id:		9
Current database:	
Current user:		[email protected]
SSL:			Cipher in use is DHE-RSA-AES256-SHA
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server version:		5.7.18-log MySQL Community Server (GPL)
Protocol version:	10
Connection:		127.0.0.1 via TCP/IP
Server characterset:	utf8mb4
Db     characterset:	utf8mb4
Client characterset:	utf8
Conn.  characterset:	utf8
TCP port:		3307
Uptime:			23 hours 16 min 56 sec

Threads: 1  Questions: 102  Slow queries: 0  Opens: 170  Flush tables: 1  Open tables: 163  Queries per second avg: 0.001
--------------



MySQL 5.7.6之前的版本

默认SSL是关闭的

mysql> show variables like "%have%ssl%";
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
+---------------+----------+
2 rows in set (0.00 sec)

首先,需要创建CA文件(先有ca-key.pem再有ca.pem)

[root@237_21 mysql3306]# openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
.................+++
...............................+++
e is 65537 (0x10001)
[root@237_21 mysql3306]# openssl req -new -x509 -nodes -days 3600 \
> -key ca-key.pem -out ca.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

公私钥文件(服务端用)

[root@237_21 mysql3306]# openssl req -newkey rsa:2048 -days 3600 \
> -nodes -keyout server-key.pem -out server-req.pem
Generating a 2048 bit RSA private key
.........................+++
.................................................................+++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@237_21 mysql3306]# 
[root@237_21 mysql3306]# openssl rsa -in server-key.pem -out server-key.pem
writing RSA key
[root@237_21 mysql3306]# 
[root@237_21 mysql3306]# openssl x509 -req -in server-req.pem -days 3600 \
> -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key

公私钥文件(客户端用)

[root@237_21 mysql3306]# openssl req -newkey rsa:2048 -days 3600 \
> -nodes -keyout client-key.pem -out client-req.pem
Generating a 2048 bit RSA private key
...........+++
...........................................................................................................................+++
writing new private key to 'client-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@237_21 mysql3306]# openssl rsa -in client-key.pem -out client-key.pem
writing RSA key
[root@237_21 mysql3306]# 
[root@237_21 mysql3306]# openssl x509 -req -in client-req.pem -days 3600 \
> -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key
[root@237_21 mysql3306]# 

最后,不要忘记修改秘钥文件权限

# chown -R mysql.mysql ./*


my.cnf中,加入以下参数,并重启

######SSL#######
ssl-ca=ca.pem
ssl-cert=server-cert.pem
ssl-key=server-key.pem

mysql> show variables like "%ssl%";
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
9 rows in set (0.02 sec)


再次使用root账户登录,并指定秘钥文件

[root@237_21 mysql3306]# mysql -uroot -p -h 127.0.0.1 -P3306 --ssl-cert=/data/mysql3306/client-cert.pem --ssl-key=/data/mysql3306/client-key.pem
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.6.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.6.36, for linux-glibc2.5 (x86_64) using  EditLine wrapper

Connection id:		8
Current database:	
Current user:		[email protected]
SSL:			Cipher in use is DHE-RSA-AES256-SHA
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server version:		5.6.36-log MySQL Community Server (GPL)
Protocol version:	10
Connection:		127.0.0.1 via TCP/IP
Server characterset:	utf8mb4
Db     characterset:	utf8mb4
Client characterset:	utf8
Conn.  characterset:	utf8
TCP port:		3306
Uptime:			11 min 33 sec

Threads: 1  Questions: 21  Slow queries: 0  Opens: 70  Flush tables: 1  Open tables: 63  Queries per second avg: 0.030
--------------



参考文档:

1、SSL Connections in MySQL 5.7

https://www.percona.com/blog/2017/06/27/ssl-connections-in-mysql-5-7/

2、MySQL5.7的SSL测试

http://www.cnblogs.com/mysql-dba/p/7061300.html


猜你喜欢

转载自blog.csdn.net/leonpenn/article/details/78016000