0


MySQL SSL安全解读

安全一直是不可不重视的问题。目前MySQL这方面应大方向上技术手段都具备。如:网络链接,权限控制,key秘钥认证,数据加密脱敏 等方式。综合考虑,虽然很多环境无法所有这些安全策略全部应用上,但在可控范围内尽量做到一定的防范实施。

其中SSL是属于加密连接方式,提供以下安全服务:

  1. 客户机和服务器之间的,通过使用公开密钥和对称密钥技术以达到信息保密。
  2. 信息完整性,确保SSL业务全部达到目的。应确保服务器和客户机之间的信息内容免受破坏。
  3. 双向认证,客户机和服务器相互识别的过程。它们的识别号用公开密钥编码,并在SSL握手时交换各自的识别号。
  4. 安全性服务对终端用户来讲做到尽可能透明。

SSL介绍

SSL定义:

SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。

SSL证书:

SSL安全证书是由权威认证机构颁发的,是CA机构将公钥和相关信息写入一个文件,CA机构用私钥对公钥和相关信息进行签名后,将签名信息也写入这个文件后生成的一个文件。 简单理解就是客户申请后,签发机构给一个唯一的文件,然后客户安装到服务器上进行使用,这个唯一的文件就是SSL证书。

备注:
X.509:是一种证书格式,对X.509证书来说,认证者总是CA或由CA指定的人,一份X.509证书是一些标准字段的集合,这些字段包含有关用户或设备及其相应公钥的信息。
OpenSSL 相当于SSL的一个实现,如果把SSL规范看成接口,那么OpenSSL则认为是接口的实现。

MySQL里SSL使用方式

MySQL中SSL功能支持客户端到服务器端的认证。主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性。

TLS(Transport Layer Security)是更为安全的升级版SSL。SSL表示安全套接字层,而TLS表示传输层安全。

实际上,目前MySQL使用的就是TLS协议,而不是单纯的SSL协议(如:status的ssl信息TLS_AES_256_GCM_SHA384)

mysql> status
--------------
mysql  Ver 8.0.31 for Linux on x86_64 (MySQL Community Server - GPL)

Connection id:        22
Current database:    
Current user:        ssluser@iZuf6178v14ipc59jbbpfnZ
SSL:            Cipher in use is TLS_AES_256_GCM_SHA384
                        #表示用户采用SSL连接到mysql服务器如上,如果不是显示"Not in use"
。。。
--------------

MySQL中SSL和RSA文件具有以下特征:

  • SSL和RSA密钥的大小为2048位。
  • SSL CA证书是自签名的。
  • 使用sha256WithRSAEncryption签名算法,使用CA证书和密钥对SSL服务器和客户端证书进行签名。
  • SSL证书使用以下通用名称(CN)值以及相应的证书类型(CA,服务器,客户端):
ca.pem:         MySQL_Server_suffix_Auto_Generated_CA_Certificate
server-cert.pm: MySQL_Server_suffix_Auto_Generated_Server_Certificate
client-cert.pm: MySQL_Server_suffix_Auto_Generated_Client_Certificate

后缀的值基于MySQL的版本号。由mysql_ssl_rsa_setup执行生成的文件,也可以使用suffix选项显式指定后缀。对于服务器生成的文件,如果生成的CN值超过64个字符,则省略名称的_suffix部分。

  • SSL文件的“国家”©、“州或省”(ST)、“组织”(O)、“组织单位名称”(OU)和“电子邮件地址”为空。
  • 由服务器或mysql_ssl_rsa_setup创建的SSL文件自生成之日起10年内有效。
  • RSA文件不过期。
  • 对于每个证书/密钥对,SSL文件具有不同的序列号(1用于CA, 2用于服务器,3用于客户机)。
  • 由服务器自动创建的文件由运行服务器的帐户拥有。使用mysql_ssl_rsa_setup创建的文件由调用该程序的用户拥有。可以通过chown调用的系统上进行更改,如果程序是由root调用的,并且给出了——uid选项来指定应该拥有文件的用户。
  • 在Unix和类系统上,证书文件的文件访问模式是644(即世界可读),密钥文件的文件访问模式是600(即仅由运行服务器的帐户访问)。

ssl文件可以通过Openssl命令手动生成,但mysql里已经提供mysql_ssl_rsa_setup自动创建:

#执行创建证书命令前先停止msyql实例
shell> mysql_ssl_rsa_setup --datadir=/opt/data8.0 --verbose
2022-12-08 10:15:22 [NOTE]    Destination directory: /opt/data8.0
2022-12-08 10:15:22 [NOTE]    Executing : openssl version
OpenSSL 1.1.1k  FIPS 25 Mar 2021
2022-12-08 10:15:22 [NOTE]    Executing : openssl req -newkey rsa:2048 -days 3650 -nodes -keyout ca-key.pem -subj /CN=MySQL_Server_8.0.31_Auto_Generated_CA_Certificate -out ca-req.pem && openssl rsa -in ca-key.pem -out ca-key.pem
Ignoring -days; not generating a certificate
Generating a RSA private key
.............................................................................................+++++
................................................................................+++++
writing new private key to 'ca-key.pem'
-----
writing RSA key
2022-12-08 10:15:22 [NOTE]    Executing : openssl x509 -sha256 -days 3650 -extfile cav3.ext -set_serial 1 -req -in ca-req.pem -signkey ca-key.pem -out ca.pem
Signature ok
subject=CN = MySQL_Server_8.0.31_Auto_Generated_CA_Certificate
Getting Private key
。。。
..................................+++++
...................................................+++++
writing new private key to 'server-key.pem'
-----
writing RSA key
2022-12-08 10:15:22 [NOTE]    Executing : openssl x509 -sha256 -days 3650 -extfile certv3.ext -set_serial 2 -req -in server-req.pem -CA ca.pem -CAkey ca-key.pem -out server-cert.pem
Signature ok
subject=CN = MySQL_Server_8.0.31_Auto_Generated_Server_Certificate
Getting CA Private Key
。。。
..+++++
..............................................................................................................+++++
writing new private key to 'client-key.pem'
-----
writing RSA key
2022-12-08 10:15:23 [NOTE]    Executing : openssl x509 -sha256 -days 3650 -extfile certv3.ext -set_serial 3 -req -in client-req.pem -CA ca.pem -CAkey ca-key.pem -out client-cert.pem
Signature ok
subject=CN = MySQL_Server_8.0.31_Auto_Generated_Client_Certificate
Getting CA Private Key
2022-12-08 10:15:23 [NOTE]    Executing : openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
2022-12-08 10:15:23 [NOTE]    Executing : openssl genrsa  -out private_key.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.............................+++++
.+++++
e is 65537 (0x010001)
2022-12-08 10:15:23 [NOTE]    Executing : openssl rsa -in private_key.pem -pubout -out public_key.pem
writing RSA key
2022-12-08 10:15:23 [NOTE]    Success!

生成的8个pem文件:

shell> ll data/mysql/*.pem
-rw------- 1 mysql mysql 1676 Dec  6 11:11 ca-key.pem
-rw-r--r-- 1 mysql mysql 1112 Dec  6 11:11 ca.pem
-rw-r--r-- 1 mysql mysql 1112 Dec  6 11:11 client-cert.pem
-rw------- 1 mysql mysql 1676 Dec  6 11:11 client-key.pem
-rw-r--r-- 1 mysql mysql 1680 Sep 19 23:35 private_key.pem
-rw-r--r-- 1 mysql mysql  452 Sep 19 23:35 public_key.pem
-rw-r--r-- 1 mysql mysql 1112 Dec  6 11:11 server-cert.pem
-rw------- 1 mysql mysql 1680 Dec  6 11:11 server-key.pem

文件说明ca.pemCA证书ca-key.pemCA证书密钥client-cert.pem客户端使用的证书client-key.pem客户端使用的密钥server-cert.pem服务端使用的证书server-key.pem服务端使用的密钥private_key.pem私钥public_key.pem公钥

  • 查看SSL证书的内容: 检查它的有效日期范围,调用openssl命令:
shell> openssl x509 -text -in client-cert.pem 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 3 (0x3)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = MySQL_Server_8.0.31_Auto_Generated_CA_Certificate
        Validity
            Not Before: Dec  6 03:11:19 2022 GMT
            Not After : Dec  3 03:11:19 2032 GMT
        Subject: CN = MySQL_Server_8.0.31_Auto_Generated_Client_Certificate
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c9:ea:ec:b1:9a:88:99:33:2f:e9:17:cc:d2:4a:
                    ↓
                    91:9d:b4:ee:66:19:7a:b1:fb:ca:ae:4a:d5:41:c6:
                    a4:eb
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
    Signature Algorithm: sha256WithRSAEncryption
         6f:09:b9:7d:d7:83:6c:72:3f:c4:8a:17:2a:f6:c7:0d:4a:22:
         ↓
         a5:2f:1a:e4
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADA8MTowOAYDVQQDDDFNeVNR
↓
eTixiNaMvkBXxDUky4xWZ00XU76ei6pWE8h1wP6OfUpw8NFZ7Wt4/dvRD2AtFxDH
PB0i6ppH/KUvGuQ=
-----END CERTIFICATE-----
  • 通过SQL语句检查SSL证书过期时间:
mysql>  SHOW STATUS LIKE 'Ssl_server_not%';
+-----------------------+--------------------------+
| Variable_name         | Value                    |
+-----------------------+--------------------------+
| Ssl_server_not_after  | Dec  3 03:11:19 2032 GMT |
| Ssl_server_not_before | Dec  6 03:11:19 2022 GMT |
+-----------------------+--------------------------+
2 rows in set (0.00 sec)
  • 配置文件设置
[mysqld]
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem
require_secure_transport=ON

备注:require_secure_transport参数
客户端与服务器的连接是否需要使用某种形式的安全传输。启用此变量后,服务器仅允许使用TLS/SSL加密的TCP/IP连接,或使用套接字文件(在Unix上)或共享内存(在Windows上)的连接。
此功能补充了每个帐户的SSL要求,这些要求优先。例如,如果使用REQUIRE SSL定义帐户,下面有介绍账号生成规则。

  • 密钥文件的访问权限: 私钥只能由服务器读取,而公钥可以自由分发给客户端用户。
chmod 400 private_key.pem
chmod 444 public_key.pem
  • Client重用SSL: 从MySQL 8.0.29开始,客户端程序可以选择恢复前的SSL的session,前提是服务器在其运行时缓存中有该会话。SSL重用当然是为了减少重新创建链接开销。
  1. 服务器必须将其会话缓存保存在内存中。
  2. 服务器端会话缓存超时必须未过期。
  3. 每个客户端都必须维护活动会话的缓存并保持其安全
#ssl_session_cache开启和重用有效时间
mysql> SHOW VARIABLES LIKE '%ssl_session%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| ssl_session_cache_mode    | ON    |
| ssl_session_cache_timeout | 300   |
+---------------------------+-------+
2 rows in set (0.01 sec)

#ssl_session状态
mysql> SHOW STATUS LIKE 'Ssl_session%';
+-----------------------------+--------+
| Variable_name               | Value  |
+-----------------------------+--------+
| Ssl_session_cache_hits      | 0      |
| Ssl_session_cache_misses    | 0      |
| Ssl_session_cache_mode      | SERVER |
| Ssl_session_cache_overflows | 0      |
| Ssl_session_cache_size      | 128    |
| Ssl_session_cache_timeout   | 300    |
| Ssl_session_cache_timeouts  | 0      |
| Ssl_sessions_reused         | 0      |
+-----------------------------+--------+
8 rows in set (0.00 sec)

MySQL客户端程都能够重用先前的会话,用于与同一服务器建立新的加密连接,前提是在原始连接仍处于活动状态时存储会话数据。会话数据存储到一个文件中,在再次调用客户端时指定该文件。

#调用ssl_session_data_print命令指定可以安全地存储当前活动会话数据的文件的路径

mysql> ssl_session_data_print ~/private-dir/session.txt 

#调用任何MySQL客户端来建立到同一服务器的新的加密连接。重用会话数据

shell> mysql -u admin -p --ssl-session-data=~/private-dir/session.txt

SSL如何使用

  • 链接客户端工具: 如果不想使用ssl则增加–ssl=0选项或–ssl-mode=DISABLED
shell> mysql -uroot -proot --ssl=0或
shell> mysql -uroot -proot --ssl-mode=DISABLED

#参数ssl指定
shell> mysql -ussluser -p -P3306 -h192.168.1.1 
      --ssl-ca=/opt/ca.pem 
      --ssl-key=/opt/client-key.pem 
      --ssl-cert=/opt/client-cert.pem 
  • 用户使用强制使用SSL: ssl用户有如下参数tls_option: { SSL : 帐户下分发的语句进行加密连接。 | X509 : 客户端必须发送一个有效的X509证书 | CIPHER ‘cipher’ : 指定加密算法 | ISSUER ‘issuer’ :客户端的证书是否是服务器所配置的CA颁发 | SUBJECT ‘subject’ : 认证证书的subject | NONE : 不进行认证 }
#新建用户 ssl mysql> GRANT SELECT ON *.* to 'dba'@'%' IDENTIFIED BY 'xxx' REQUIRE SSL; #修改用户 mysql> ALTER USER 'dba'@'%' REQUIRE SSL; mysql> FLUSH PRIVILEGES; 
  • 驱动程序: 如:jdbc设置ssl
driverClassName=com.mysql.cj.jdbc.Driver

"jdbc:mysql://192.168.244.1:3306/sample?useUnicode=true&useSSL=true&
trustCertificateKeyStorePassword=123456&serverTimezone=Asia/Shanghai&
trustCertificateKeyStoreUrl=http://localhost:8080/mysql.ks

如果直接配置了连接属性verifyServerCertificate=true&useSSL=true&requireSSL=true,启动项目会报错,缺少证书
trustCertificateKeyStorePassword=设置的密钥,
trustCertificateKeyStoreUrl=当前服务器可访问到证书的地址,
useSSL=true,verifyServerCertificate=true代表需要客户端密钥库和信任库

备注:可以使用jdk自带的keytool工具导入mysql客户端证书到密钥仓库,并生成秘钥仓库文件。

  • Navicat客户端配置ssl: 需要CA.pem,client-key.pem,client-ceart.pem文件
  • caching_sha2_password: MySQL Server 使用 caching_sha2_password(MySQL8.0默认的认证插件)、sha256_password 认证插件,则还必须指定 AllowPublicKeyRetrieval=True,因为 caching_sha2_password 插件要求交换密码时必须使用 RSA 公钥加密
shell> mysql -udbadmin -p123456  -h192.168.1.1 -P3380 \
       --server-public-key-path=/opt/data/public_key.pem

性能测试

开启SSL后,必定带来的一定的性能影响。从SSL实现来看,建立连接时需要进行握手、加密、解密等操作,之后数据传输也有包含加密解密过程。所以耗时大的一般在建立连接阶段。
sysbench对于ssl-key参数没开放,简单采用mysqlslap进行测试

shell> mysqlslap -ussluser -p123456 -P3380 -h192.168.244.129  \
       --ssl-ca=/opt/ca.pem \
       --ssl-key=/opt/client-key.pem \
       --ssl-cert=/opt/client-cert.pem  \
       --create-schema=test -a -c 38 -i 500

数据库TPS/QPS平均降低了10~20%。还是比较影响性能的。对于使用短链接的应用程序可能产生更大的性能损耗,比如采用PHP开发。不过如果使用连接池 或 长连接可能会好许多。

总结

SSL安全能预防诸多一定程度的攻击。在传输过程中,如被黑客截获加密数据,在没有私有解密密钥的情况下无法读取或使用它。 可以说SSL使得更加安全。对于MySQL国内环境中,SSL使用场景还是比较少,因为数据库和应用之间内部网络进行交互,除此之外 外围防火墙也会起到很好的隔离作用。

  1. MySQL5.7高版本 MySQL8.0默认是开启SSL连接,如果强制用户使用SSL,那么应用配置也需要明确指定SSL相关参数,否则程序会报错;
  2. SSL下tcpdump类似抓包工具,是无法抓到 或 抓到了也无法看到信息;
  3. SSL下复制集(主从复制,MGR集群)都需要设置SSL配置协议;
  4. 虽然SSL方式使得安全性提高,但是相对地使得TPS/QPS也降低10%~20%。所以要谨慎选择;
  5. 对于非常敏感核心的数据,性能损失,换来的更高的数据安全性;
  6. 对于采用短链接、要求高性能的应用,或 不产生核心敏感数据的应用,性能和可用性才是首要,建议不要采用SSL方式;
标签: ssl mysql 安全

本文转载自: https://blog.csdn.net/dreamyuzhou/article/details/128285852
版权归原作者 Kevin崔 所有, 如有侵权,请联系我们删除。

“MySQL SSL安全解读”的评论:

还没有评论