如何使用相互TLS / SSL加密从Java JDBC连接到SQL DB

时间:2019-08-22 12:59:57

标签: java mysql jdbc google-cloud-platform tls1.2

今天,云数据库非常流行,有时我们需要从笔记本电脑或类似设备连接到一个数据库。通常,有一个未加密连接的选项,但这不是很安全。那么,如何连接到相互的TLS mysql服务器(如Google Cloud SQL)?

从mysql cli中,从Google云控制台下载服务器ca证书,客户端证书和密钥后,操作非常简单:

mysql -u <user-name> -h <server-ip> -p --ssl-ca=server-ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem

注意:对于Google云,您也可以使用Cloud SQL代理,但我想在没有该代理的情况下进行连接

2 个答案:

答案 0 :(得分:0)

下面的Logstash 7和jvm 9 +。

好的,我终于弄清楚了,将来自不同来源的信息拼凑在一起。此解决方案已通过Google Cloud SQL和休眠模式进行了测试,但也可以在其他设置中使用。

该解决方案要求使用Java密钥库(客户端证书/密钥)和信任库(服务器CA证书),并传递一些jdbc URL参数和JVM选项。

首先,让我们从server-ca.pem文件创建一个信任库

keytool -importcert -alias gcpRoot -file server-ca.pem -keystore truststore.jks -storepass <chose a password and remember>

编辑:或者将CA添加到现有的cacerts文件的jvm中(以确保其他https调用可以正常工作),将其重命名的cacerts复制到truststore.jks并运行:

OR: keytool -importcert -alias gcpRoot -file server-ca.pem -keystore truststore.jks -storepass changeit

第二,我们需要分两步将客户端证书和密钥导入密钥库文件(我使用SQL用户名作为别名,但我认为这并不重要)

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out keystore.p12 -name "<keystore-alias>" -passout pass:<chose a password and remember>
keytool -importkeystore -alias <keystore-alias> -srckeystore keystore.p12  -srcstoretype pkcs12 -destkeystore keystore.jks -srcstorepass <insert same password here> -deststoretype JKS -deststorepass <password-for-output-jks-keystore>

接下来,我们需要修改jdbc连接URL(注意!某些IDE(例如intelliJ)需要转义 & 并替换为 &amp;

jdbc:mysql://<server-ip>/<db-name>?verifyServerCertificate=true&useSSL=true&requireSSL=true

最后,我们需要提供密钥库和信任库的位置和密码作为JVM参数:

-Djavax.net.ssl.trustStore="truststore.jks"
-Djavax.net.ssl.trustStorePassword="<password>"
-Djavax.net.ssl.keyStore="keystore.jks"
-Djavax.net.ssl.keyStorePassword="<password>"

更新: 如果您运行的是9版或更高版本的jvm(例如7+的logstash docker映像),则需要解决一些类加载问题,以使jdbc驱动程序均匀加载,并且您需要使用最新版本的mysql驱动程序TLS正常工作。

首先,您显然必须将jdbc驱动程序的.jar文件放在<logstash-dir>/logstash-core/lib/jars/mysql-connector-java-8.0.17.jar中(这将导致jar自动加载)。而且我们还需要在输入配置中添加以下内容:

jdbc_driver_library => ""
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"

由于某种原因,我仍然收到警告Loading class com.mysql.jdbc.Driver. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver'`,但是尽管出现此警告,它仍然可以工作。

答案 1 :(得分:0)

虽然不能完全回答这个问题,但我将添加此示例,说明如何与在kubernetes上部署的logstash jdbc插件一起使用,因为它并不完全简单明了,并且可能对类似系统有用。

此解决方案基于第一个解决方案,但是 truststore 必须基于完整的.registry.npmjs.org JVM。

在输入定义中,将参数添加到jdbc URL:

cacerts

然后从信任和密钥库以及mysql密码创建一个秘密:

input {
  jdbc {
    ...
    jdbc_connection_string => "jdbc:mysql://<server-ip>:3306/<db>?verifyServerCertificate=true&useSSL=true&requireSSL=true"
    jdbc_password => "${MYSQL_PASSWORD}"
    ...
  }
}

然后,我们修改部署Yaml以安装凭据,并添加LS_JAVA_OPTS指向它们:

kubectl create secret generic java-tls-creds --from-file=./keystore.jks --from-file=./truststore.jks
kubectl create secret generic mysql-password --from-literal='password=<password>'