mysql启用ssl数据加密

SSL(Secure Socket Layer,安全套接层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯,防止数据中途被窃取

[TOC]

启用ssl加密步骤

  • 第1步,mysql 5.7.6及以上版本可利用 mysql_ssl_rsa_setup 生成用于加密和解密mysql连接的私钥证书(mysql8.0亦如此)
[root@localhost ~]# mysql_ssl_rsa_setup --user=mysql --datadir=/data/mysql_3306/var

[root@localhost ~]# ls -l /data/mysql_3306/var/*.pem
-rw-------. 1 mysql mysql 1676 Nov 30 22:32 /data/mysql_3306/var/ca-key.pem             #CA私钥
-rw-r--r--. 1 mysql mysql 1120 Nov 30 22:32 /data/mysql_3306/var/ca.pem                 #自签的CA证书,客户端连接也需要提供
-rw-r--r--. 1 mysql mysql 1120 Nov 30 22:32 /data/mysql_3306/var/client-cert.pem        #客户端连接服务器端需要提供的证书文件
-rw-------. 1 mysql mysql 1680 Nov 30 22:32 /data/mysql_3306/var/client-key.pem         #客户端连接服务器端需要提供的私钥文件
-rw-------. 1 mysql mysql 1676 Nov 30 22:32 /data/mysql_3306/var/private_key.pem        #私钥/公钥对的私有成员
-rw-r--r--. 1 mysql mysql  452 Nov 30 22:32 /data/mysql_3306/var/public_key.pem         #私钥/公钥对的共有成员
-rw-r--r--. 1 mysql mysql 1120 Nov 30 22:32 /data/mysql_3306/var/server-cert.pem        #服务器端证书文件
-rw-------. 1 mysql mysql 1680 Nov 30 22:32 /data/mysql_3306/var/server-key.pem         #服务器端私钥文件
  • 第2步,修改 my.cnf 配置ssl证书
[mysqld]
ssl=1
ssl-ca=/data/mysql_3306/var/ca.pem
ssl-cert=/data/mysql_3306/var/server-cert.pem
ssl-key=/data/mysql_3306/var/server-key.pem
  • 第3步,开启或关闭SSL加密,需要重启mysql服务以生效
ps -ef | grep mysql | grep -v grep | awk '{print $2}' | xargs kill -9 2>/dev/null
mysqld_safe --defaults-file=/data/mysql_3306/my_3306.cnf &
  • 第4步,使用ssl连接mysql,并确认ssl已启用
[root@localhost ~]# cd /data/mysql_3306/var/
[root@localhost ~]# mysql -h 127.0.0.1 -udba_admin -p --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem

mysql> show variables where variable_name in ('have_ssl','ssl_ca','ssl_cert','ssl_key');
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| have_ssl      | YES                                  |
| ssl_ca        | /data/mysql_3306/var/ca.pem          |
| ssl_cert      | /data/mysql_3306/var/server-cert.pem |
| ssl_key       | /data/mysql_3306/var/server-key.pem  |
+---------------+--------------------------------------+

mysql> show status like 'Ssl_cipher';
+---------------+-----------------------------+
| Variable_name | Value                       |
+---------------+-----------------------------+
| Ssl_cipher    | ECDHE-RSA-AES128-GCM-SHA256 |  #.加密套件
+---------------+-----------------------------+

mysql> show global variables like 'tls_version';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| tls_version   | TLSv1,TLSv1.1,TLSv1.2 |  #.从mysql 5.7.35开始,不推荐使用TLSv1和TLSv1.1协议,而mysql8.0则默认只启用TLSv1.2协议
+---------------+-----------------------+

mysql> \s
Current user:           dba_admin@127.0.0.1
SSL:                    Cipher in use is ECDHE-RSA-AES128-GCM-SHA256     #.表示该用户采用SSL连接,如果不是ssl则显示 Not in use

应用程序配置ssl连接

  • 第1步,新建用户强制使用ssl连接
#.mysql5.7支持在create user及grant中require ssl,但mysql8.0只支持在create user的时候require ssl
create user if not exists 'ssltest'@'%' identified by 'Admin_147' require ssl;
grant select on *.* to 'ssltest'@'%';
flush privileges;
  • 第2步,开启强制SSL后,用户连接mysql使用TCP方式连接默认会使用SSL,无需加其他选项
[root@localhost ~]# cd /data/mysql_3306/var/
[root@localhost ~]# mysql -ussltest -pAdmin_147 -h127.0.0.1
mysql> \s
Current user:           ssltest@127.0.0.1
SSL:                    Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
  • 第3步,开启强制SSL后,用户连接mysql如果通过--ssl-mode=disabled手动关闭SSL,则无法连接上数据库
[root@localhost ~]# cd /data/mysql_3306/var/
[root@localhost ~]# mysql -ussltest -pAdmin_147 -h127.0.0.1 --ssl-mode=disabled
ERROR 1045 (28000): Access denied for user 'ssltest'@'127.0.0.1' (using password: YES)
  • 第4步,修改代码中的连接字符串,通过 useSSL=true 启用ssl,示例如下:
jdbc:mysql://127.0.0.1:3306/testdb?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=Asia/Shanghai\
&useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificate=<path_to_cert>

指定用户强制使用ssl连接

  • 指定用户是否强制使用SSL连接
#.设置已存在用户是否使用ssl连接
alter user 'ssltest'@'%' require none;      #.非强制,也是默认选项
alter user 'ssltest'@'%' require ssl;       #.强制用户使用SSL连接
alter user 'ssltest'@'%' require x509;      #.使用X509方式的SSL,客户端必须提供ca文件才可以登录

#.确认用户是否强制使用ssl连接
select user,host,ssl_type from mysql.user;

附录

启用ssl的安全性对比

  • 场景1:在app服务器(比如10.30.3.231)上,利用mysql客户端登录数据库并执行insert操作,使用 --ssl-mode=disabled 关闭SSL
[root@localhost ~]# mysql -h 127.0.0.1 -udba_admin -p --ssl-mode=disabled
mysql> create table testdb.tb01(id int, name varchar(10));
mysql> insert into testdb.tb01 values(1,'aaa')
  • 结论1:在未使用SSL情况下,在mysql服务器(比如10.30.3.231)上,利用tshark进行抓包可以获取数据,安全性不高。
  • 场景2:在app服务器(比如10.30.3.231)上,利用mysql客户端登录数据库并执行insert操作,使用 --ssl-mode=required 指定SSL
[root@localhost ~]# mysql -h 127.0.0.1 -udba_admin -p --ssl-mode=required
mysql> create table testdb.tb01(id int, name varchar(10));
mysql> insert into testdb.tb01 values(2,'bbb')
  • 结论2:采用SSL加密后,在mysql服务器(比如10.30.3.231)上,利用tshark抓不到数据,安全性高。

启用ssl的性能对比

  • 开启SSL会增加网络连接响应时间和CPU消耗,开启前请评估对业务的性能影响
  • 开启SSL后,建立连接时需要进行握手、加密、解密等操作。根据经验,数据库QPS平均降低了23%左右,相对还是比较影响性能的。
  • 一般耗时基本都在建立连接阶段,这对于使用短链接的应用程序(比如php)可能产生更大的性能损耗,不过如果使用连接池或者长连接可能会好许多
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2023-12-06 11:00:57

results matching ""

    No results matching ""