【问题标题】:How to connect to SQL DB from Java JDBC with mutual TLS/SSL encryption如何通过相互 TLS/SSL 加密从 Java JDBC 连接到 SQL DB
【发布时间】:2019-12-27 19:31:32
【问题描述】:

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

从 mysql cli 从谷歌云控制台下载服务器 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 代理,但我想在没有它的情况下进行连接

【问题讨论】:

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


    【解决方案1】:

    虽然这不是问题的确切答案,但我将添加这个示例,说明如何使用部署在 kubernetes 上的 logstash jdbc 插件进行此操作,因为它不是完全直接的,它可能对类似系统有用。

    此解决方案基于第一个解决方案,但 truststore 必须基于 jvm 的完整 cacerts

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

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

    然后从信任和密钥库中创建一个秘密并为 mysql 密码:

    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>'
    

    然后我们修改部署 yaml 以挂载凭据并添加 LS_JAVA_OPTS 以指向它们:

    apiVersion: apps/v1
    kind: Deployment
    ... 
            env:
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: password
            - name: LS_JAVA_OPTS
              value: -Djavax.net.ssl.keyStore=/java-tls-creds/keystore.jks -Djavax.net.ssl.keyStorePassword=<password> -Djavax.net.ssl.trustStore=/java-tls-creds/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit
    ...
            volumeMounts:
            - name: java-tls-creds
              mountPath: "/java-tls-creds"
              readOnly: true
    ...
          volumes:
          - name: java-tls-creds
            secret:
              secretName: java-tls-creds
    

    【讨论】:

      【解决方案2】:

      Logstash 7 和 jvm 9+ 以下。

      好的,我终于想出了将不同来源的信息拼凑在一起的方法。此解决方案已使用 google cloud SQL 和 hibernate 进行了测试,但也应适用于其他设置。

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

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

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

      编辑:或者将 CA 添加到 jvms 现有的 cacerts 文件中(以确保其他 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;amp; 转义并替换为 &amp;amp;

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

      最后,我们需要提供 keystore 和 truststore 的位置和密码作为 JVM 参数:

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

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

      首先您显然必须将 jdbc 驱动程序的 .jar 文件放在&lt;logstash-dir&gt;/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 iscom.mysql.cj.jdbc.Driver'` 但尽管有此警告,它仍然有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-26
        • 1970-01-01
        • 2016-07-18
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多