簡體   English   中英

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

[英]How to connect to SQL DB from Java JDBC with mutual TLS/SSL encryption

今天,雲數據庫非常流行,有時我們需要從便攜式計算機或類似設備連接到一個數據庫。 通常,有一個未加密連接的選項,但這不是很安全。 那么,如何連接到相互的TLS mysql服務器(如Google Cloud SQL)?

從mysql cli中,從Google Cloud Console下載服務器ca cert,客戶端cert和密鑰后,操作相當簡單:

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,您也可以使用Cloud SQL代理,但我想在沒有該代理的情況下進行連接

下面的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添加到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;

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 Loading class com.mysql.jdbc.Driver. This is deprecated. The new driver class is Loading class com.mysql.jdbc.Driver. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver',但盡管出現此警告,它仍可以工作。

雖然不是完全不是這個問題的答案,但我將添加此示例,說明如何與在kubernetes上部署的logstash jdbc插件一起使用,因為它並不完全簡單明了,並且可能對類似系統有用。

該解決方案基於第一個解決方案,但是信任庫必須基於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM