菜单

Administrator
发布于 2023-11-15 / 37 阅读
0
0

mysql5.7启动SSL

说明

在一些要求安全的项目,我们mysql需要开启ssl加密。

配置

  1. 在服务器执行mysql自带的生成证书的脚本
mysql_ssl_rsa_setup
  1. 生成后,可以在/var/lib/mysql/目录下,看到生成的8个的证书pem文件

测试发现,不用执行mysql_ssl_rsa_setup,mysql安装后默认就有了

1700032074615
3. 对这些pem文件赋权限

chmod +x /var/lib/mysql/*.pem
  1. 编辑/etc/my.cnf配置文件,在[mysqld]增加以下内容
ssl=1
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem
  1. 重启服务
systemctl restart mysqld
  1. 连接测试(双向验证)
mysql -uroot -p --ssl-ca=/var/lib/mysql/ca.pem --ssl-cert=/var/lib/mysql/client-cert.pem --ssl-key=/var/lib/mysql/client-key.pem
  1. 执行\s,可以看到生效
    1700032344091

  2. 在本地执行mysql连接时,可以不带证书相关的参数(3个–ssl开头的参数),也是可以连接上的,此时SSL状态为Not is use
    1700032483369

  3. 通过上面的配置,客户端可以选择用SSL连接,不带证书连接也能连接上,我们可以在[mysqld]增加以下内容,强制需要证书才能连接(重启生效)

require_secure_transport=ON

注意,开启有,本地的mysql还是可以不带证书连接的,只是影响了第三方客户端连接而已。

  1. navicat使用ssl
    单向验证:
    1700117548510
    双向验证:
    1700032911269

JDBC连接

基本SSL连接

基本SSL连接,在连接时,增加下面三个参数,代表使用SSL连接。

  • useSSL=true
  • requireSSL=true
  • verifyServerCertificate=true
jdbc:mysql://127.0.0.1:3306/database?useSSL=true&requireSSL=true&verifyServerCertificate=true

由于我们使用的是自签名的证书,所以JDBC在验证服务器端的SSL证书时,会提示:Path does not chain with any of the trust anchors。我们可以将verifyServerCertificate改为false来处理这个问题。

verifyServerCertificate为参数用于控制 SSL 连接时是否验证服务器端的 SSL 证书,该参数的作用是确定是否强制要求服务器端提供有效且受信任的 SSL 证书,以确保建立的连接是安全的。

当 verifyServerCertificate 参数设置为 true(默认值)时,JDBC 将验证服务器端提供的 SSL 证书。它会检查证书的有效性、颁发机构的受信任性、证书链的完整性以及主机名的匹配性。如果服务器端的证书无效、过期、不受信任或与主机名不匹配,JDBC 将拒绝建立连接,并抛出相应的 SSL 异常。

当 verifyServerCertificate 参数设置为 false 时,JDBC 将绕过对服务器端证书的验证。这意味着即使服务器端的证书无效、过期或不受信任,JDBC 仍然会建立连接。但是,请注意,将 verifyServerCertificate 设置为 false 可能会带来安全风险,因为连接的服务器无法被正确验证,存在中间人攻击等安全威胁。

“JDBC在验证服务器端的SSL证书” 中的 SSL 证书指的是服务器端的证书,而不是客户端证书。
在 SSL/TLS 握手过程中,服务器会向客户端发送其 SSL 证书,其中包含服务器的公钥。客户端使用该证书来验证服务器的身份和公钥的有效性。验证过程包括检查证书的有效性、颁发机构的受信任性、证书链的完整性以及主机名的匹配性。

如果要在verifyServerCertificate为true的情况下使用,我们需要在JDBC连接时增加以下两个参数:

  • trustCertificateKeyStoreUrl
  • trustCertificateKeyStorePassword
jdbc:mysql://127.0.0.1:3306/database?useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStoreUrl=file:///var/lib/mysql/ca.jks&trustCertificateKeyStorePassword=123456

其中ca.jks参考下面的扩展的pem证书生成jks证书步骤生成(将步骤里面client-key.pem,client-cert.pem替换为ca-key.pem,ca.pem):

openssl pkcs12 -export -out ca.p12 -inkey /var/lib/mysql/ca-key.pem -in /var/lib/mysql/ca.pem
keytool -importkeystore -srckeystore ca.p12 -srcstoretype PKCS12 -destkeystore ca.jks -deststoretype JKS

如果您使用的是自签名的证书或者由私有的证书颁发机构(CA)签发的证书,您可能需要配置一个参数来指定信任的根证书颁发机构(CA)。

在 JDBC 连接中,可以使用 trustCertificateKeyStoreUrl 和 trustCertificateKeyStorePassword 参数来指定信任的根证书颁发机构的密钥库路径和密码。这些参数用于配置信任存储(trust store),其中包含了您信任的根证书或根证书颁发机构的证书。

您可以将根证书或根证书颁发机构的证书添加到信任存储中,以便 JDBC 连接可以验证服务器端提供的证书。通过配置 trustCertificateKeyStoreUrl 和 trustCertificateKeyStorePassword 参数,JDBC 客户端将使用指定的信任存储来验证服务器端证书的有效性。

手动配置证书实现SSL连接

在 JDBC 中,通常不需要手动配置服务器端的证书路径。SSL/TLS 握手过程中会自动处理服务器端的证书验证。

当 JDBC 客户端与服务器建立 SSL 连接时,服务器会将其 SSL 证书发送给客户端。JDBC 客户端会自动获取服务器端的证书,并在 SSL/TLS 握手过程中对其进行验证。

在验证过程中,JDBC 客户端会使用操作系统或 Java 运行时环境(JRE)中的信任存储(Trust Store)来验证服务器端的证书。信任存储中包含了受信任的证书颁发机构(CA)的根证书或中间证书。如果服务器端的证书链可以追溯到信任存储中的受信任证书,且证书有效、未过期,并且主机名匹配,JDBC 客户端将验证通过,建立安全连接。

如果服务器端的证书无效、过期、不受信任或主机名不匹配,JDBC 客户端将拒绝连接,并抛出相应的 SSL 异常。

因此,在大多数情况下,您不需要手动配置服务器端的证书路径。JDBC 客户端会自动处理服务器端证书的验证,前提是您的操作系统或 JRE 的信任存储中包含了正确的受信任证书。如果您遇到证书验证相关的问题,您可能需要检查信任存储中的证书配置,并确保其正确性和完整性。

手动配置证书方法:
执行下面命令,将在服务器生成的 server-cert.pem证书导入到本地的信任存储,并生成jdbc连接时所用的jks格式的证书。

信任存储是一个包含受信任证书的存储库。您可以使用 Java 提供的 keytool 工具来创建和管理信任存储。

keytool -import -alias mytrustedcert -file server-cert.pem -keystore truststore.jks

jdbc连接时,增加以下参数

  • useSSL=true
  • requireSSL=true
  • verifyServerCertificate=true
  • trustStore=/var/lib/mysql/truststore.jks
  • trustStorePassword=123456
  • trustCertificateKeyAlias=mytrustedcert
jdbc:mysql://127.0.0.1:3306/database?useSSL=true&requireSSL=true&verifyServerCertificate=true&trustStore=file:///var/lib/mysql/truststore.jks&trustStorePassword=123456&trustCertificateKeyAlias=mytrustedcert

由于我们使用的是自签名的证书,所以JDBC在验证服务器端的SSL证书时,会提示:Path does not chain with any of the trust anchors。
如果要在verifyServerCertificate为true的情况下使用,请参考上面。

双向验证

上面的基本SSL连接和手动配置证书实现SSL连接实现的是单向验证,如要进行双向验证,即客户端也要验证服务器的身份,需提供证书给服务器,服务器进行相关配置才行。

开启双向验证,在jdbc增加下面参数

  • useSSL=true
  • requireSSL=true
  • verifyServerCertificate=true
  • clientCertificateKeyStoreUrl=file:///var/lib/mysql/client-certificate.jks
  • clientCertificateKeyStorePassword=123456
jdbc:mysql://127.0.0.1:3306/database?useSSL=true&requireSSL=true&verifyServerCertificate=true&clientCertificateKeyStoreUrl=file:///var/lib/mysql/client-certificate.jks&clientCertificateKeyStorePassword=123456

其中jks的获取参数扩展的pem证书生成jks证书。

扩展

查看pem证书内容

openssl x509 -in /path/to/self_signed_certificate.crt -text -noout

pem证书生成jks证书:

  1. 使用jdbc,需要先把客户端证书转为p12格式的证书
# OpenSSL 工具
openssl pkcs12 -export -out client-certificate.p12 -inkey /var/lib/mysql/client-key.pem -in /var/lib/mysql/client-cert.pem

回车后,会让输入证书密码,不需要密码的话,可以不用写内容;此处虽然支持空密码,但是后面执行keytool的命令时,会让输入源证书的密码,如果填空会错误,所以此处还是需要填密码。

  1. PKCS12格式证书转换为JKS格式
#  Java 的 keytool 工具
keytool -importkeystore -srckeystore client-certificate.p12 -srcstoretype PKCS12 -destkeystore client-certificate.jks -deststoretype JKS

回车后,会让输入证书密码,这时候需要填密码,不能是空;输入源密钥库口令输入上面第一步的密码。

  1. 拿到jks证书,我们在jdbc连接时就可以指定

评论